Re: [swift-evolution] [Pitch] Replace 'inout' with '&'

2015-12-18 Thread Slava Pestov via swift-evolution

> On Dec 18, 2015, at 5:30 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Dec 18, 2015, at 5:27 PM, Matthew Johnson  wrote:
>> 
>> +1.  Can you provide an example showing where you would place it though?
> 
> Good question. Three options I see:
> 
> - Before the label and binding names, where inout appears today, and where 
> other argument modifiers like `@autoclosure` go: func foo( x: Int)
> 
> which is the minimal change.
> 
> - Before the binding name: func foo(label : Int)
> 
> which is problematic for implicitly-labeled arguments.
> 
> - Before the type name: func foo(label x: )
> 
> This is the most definition-follows-use-y, but would be inconsistent with 
> other argument modifiers.

It seems the latter is the only one of the three that would also make sense for 
function types. We still need to be able to write down a function type 
containing an inout parameter right?

Also your ideas for lenses involved inout return types — how would these fit in?

> 
> -Joe
> ___
> 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] [Pitch] Make the formal type of 'self' consistent in class methods

2016-06-23 Thread Slava Pestov via swift-evolution
Consistent formal type for 'self' in class methods

Proposal: SE- 

Author: Slava Pestov 
Status: Awaiting review
Review manager: TBD

 
Introduction

This proposal makes the self value behave consistently whether or not it is 
used from a method with a Self return type.

Swift-evolution thread: Discussion thread topic for that proposal 

 
Motivation

Right now, we exhibit inconsistent behavior when self is used as an argument to 
a generic function, violating the principle of least surprise.

Consider the following code:

class Base {
  @discardableResult
  func methodWithDynamicSelf() -> Self {
doSomething(self)
return self
  }

  func methodWithoutDynamicSelf() {
doSomething(self)
  }
}

class Derived : Base {}

func doSomething(_ t: T) {
  print(T.self)
}

Base().methodWithDynamicSelf()
Base().methodWithoutDynamicSelf()

Derived().methodWithDynamicSelf()
Derived().methodWithoutDynamicSelf()
Currently, it prints the following output:

Base
Base
Derived
Base
Note that there's no inconsistency when the method is called on the base class. 
When called on the derived class however, we see that in a method with a 
dynamic Self return type, the type of self is Derived, whereas in a method with 
any other return type, the type of self is Base.


 
Proposed
 solution

The proposal is to change the type of self to always be Self, which can be 
thought of as a special generic type parameter bound to the dynamic type of the 
instance.

With this proposal, the above code will instead produce the following:

Base
Base
Derived
Derived
Here, the type of self would always be Derived when called on an instance of 
the derived class.

Of course a more useful program could instead do something with the type 
parameter T, such as constraining it to a protocol or a class with a required 
initializer, and then using the type to construct a new instance of the class.

This also dovetails nicely with SE-0068 
.

Finally, it opens the door to generalizing dynamic Self, allowing it to appear 
in covariant position within parameter types:

class ArtClass {
  func paint(withBrush: (Self) -> ()) { ... }
}
This would allow a class to conform to a protocol with a requirement written 
like the following, something that is currently not possible at all:

protocol OddProtocol {
  func weaken((Self) -> (X) -> Y) -> (X) -> Y
}

 
Detailed
 design

There's really not much more to say here. The code for typing self with a 
dynamic Self is in place already, however enabling this change might expose 
some new bugs we have not yet encountered, because currently, methods with 
dynamic Self return type are relatively rare.


 
Impact
 on existing code

This will have a small impact on existing code that uses a pattern similar to 
the above.


 
Alternatives
 considered

One alternative is to simply do nothing, but this makes the language less 
consistent than it could be.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

2016-06-23 Thread Slava Pestov via swift-evolution

> On Jun 23, 2016, at 1:30 PM, Slava Pestov <spes...@apple.com> wrote:
> 
> 
>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> When you mention the difficulty of an alternative, is that to say that it's 
>> not feasible for the GenericBox in the last example to be resolved as 
>> GenericBox? From an end-user point of view, that seems to be the most 
>> sensible behavior.
> 
> With my proposed change, GenericBox would be resolved as GenericBox in the 
> last example. Right now it fails to type check.

This should make it clearer:

struct GenericBox {
  let contents: Contents

  func transform(f: (Contents) -> Result) -> GenericBox {
// If you change this to just ‘GenericBox(contents: …)’, it does not type 
check
return GenericBox(contents: f(contents))
  }
}

func transform<Contents, Result>(box: GenericBox,
  f: (Contents) -> Result) -> GenericBox {
  // But this is totally fine!
  return GenericBox(contents: f(box.contents))
}

I suspect most people do not expect the first case to fail, and it is not 
immediately obvious why it fails when the second example type checks.

> 
> Here is an example that works right now, but would not work with my proposed 
> change:
> 
> struct GenericBox {
>   // Currently Swift resolves this as ‘GenericBox’
>   // With the new rule, we cannot infer the parameter, because there’s no 
> expression to infer it from
>   func combine(other: GenericBox) {
>   …
>   }
> }
> 
> Basically the meaning of ‘GenericBox’ right now depends on whether it appears 
> inside its own definition or extension thereof, or not. The behavior when it 
> appears elsewhere is more general — we infer the parameters from the 
> surrounding expression, instead of assuming they’re equal to the context 
> parameters.
> 
> This is a subtle change — definitely let me know if I’m not explaining it 
> well.
> 
> Slava
> 
>> On Thu, Jun 23, 2016 at 15:14 Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> Simpler interpretation of a reference to a generic type with no arguments
>> 
>> Proposal: SE- 
>> <https://github.com/slavapestov/swift-evolution/blob/silly-proposals/proposals/-simplify-unbound-generic-type.md>
>> Author: Slava Pestov <https://github.com/slavapestov>
>> Status: Awaiting review
>> Review manager: TBD
>>  
>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#introduction>Introduction
>> 
>> This proposal cleans up the semantics of a reference to a generic type when 
>> no generic arguments are applied.
>> 
>> Swift-evolution thread: Discussion thread topic for that proposal 
>> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>>  
>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#motivation>Motivation
>> 
>> Right now, we allow a generic type to be referenced with no generic 
>> arguments applied in a handful of special cases. The two primary rules here 
>> are the following:
>> 
>> If the scope from which the reference is made is nested inside the 
>> definition of the type or an extension thereof, omitting generic arguments 
>> just means to implicitly apply the arguments from context.
>> 
>> For example,
>> 
>> struct GenericBox {
>>   let contents: Contents
>> 
>>   // Equivalent to: func clone() -> GenericBox
>>   func clone() -> GenericBox {
>> return GenericBox(contents: contents)
>>   }
>> }
>> 
>> extension GenericBox {
>>   func print() {
>> // Equivalent to: let cloned: GenericBox
>> let cloned: GenericBox = clone()
>> print(cloned.contents)
>>   }
>> }
>> If the type is referenced from an unrelated scope, we attempt to infer the 
>> generic parameters.
>> 
>> For example,
>> 
>> func makeABox() -> GenericBox {
>>   // Equivalent to: GenericBox(contents: 123)
>>   return GenericBox(contents: 123)
>> }
>> The problem appears when the user expects the second behavior, but instead 
>> encounters the first. For example, the following does not type check:
>> 
>> extension GenericBox {
>> 
>>   func transform(f: Contents -> T) -> GenericBox {
>> // We resolve 'GenericBox' as 'GenericBox', rather than
>> // inferring the type parameter
>> return GenericBox(contents: f(contents))
>>   }
>> }
>>  
&g

[swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

2016-06-23 Thread Slava Pestov via swift-evolution
Simpler interpretation of a reference to a generic type with no arguments

Proposal: SE- 

Author: Slava Pestov 
Status: Awaiting review
Review manager: TBD
 
Introduction

This proposal cleans up the semantics of a reference to a generic type when no 
generic arguments are applied.

Swift-evolution thread: Discussion thread topic for that proposal 

 
Motivation

Right now, we allow a generic type to be referenced with no generic arguments 
applied in a handful of special cases. The two primary rules here are the 
following:

If the scope from which the reference is made is nested inside the definition 
of the type or an extension thereof, omitting generic arguments just means to 
implicitly apply the arguments from context.

For example,

struct GenericBox {
  let contents: Contents

  // Equivalent to: func clone() -> GenericBox
  func clone() -> GenericBox {
return GenericBox(contents: contents)
  }
}

extension GenericBox {
  func print() {
// Equivalent to: let cloned: GenericBox
let cloned: GenericBox = clone()
print(cloned.contents)
  }
}
If the type is referenced from an unrelated scope, we attempt to infer the 
generic parameters.

For example,

func makeABox() -> GenericBox {
  // Equivalent to: GenericBox(contents: 123)
  return GenericBox(contents: 123)
}
The problem appears when the user expects the second behavior, but instead 
encounters the first. For example, the following does not type check:

extension GenericBox {

  func transform(f: Contents -> T) -> GenericBox {
// We resolve 'GenericBox' as 'GenericBox', rather than
// inferring the type parameter
return GenericBox(contents: f(contents))
  }
}
 
Proposed
 solution

The proposed solution is to remove the first rule altogether. If the generic 
parameters cannot be inferred from context, they must be specified explicitly 
with the usual Type syntax.

 
Detailed
 design

This really just involves removing an existing piece of logic from the type 
resolver code.

 
Impact
 on existing code

This will have a small impact on existing code that uses a pattern similar to 
the above.

 
Alternatives
 considered

 
Status
 quo

We could keep the current behavior, but one can argue it is not very useful, 
and adds a special case where one is not needed.

 
More
 complex inference of generic parameters

We could attempt to unify the two rules for resolving a reference to a generic 
type with no arguments, however this presents theoretical difficulties with our 
constraint solver design. Even if it were easy to implement, it would increase 
type checking type by creating new possibilities to consider, with very little 
actual benefit.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

2016-06-23 Thread Slava Pestov via swift-evolution

> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> When you mention the difficulty of an alternative, is that to say that it's 
> not feasible for the GenericBox in the last example to be resolved as 
> GenericBox? From an end-user point of view, that seems to be the most 
> sensible behavior.

With my proposed change, GenericBox would be resolved as GenericBox in the 
last example. Right now it fails to type check.

Here is an example that works right now, but would not work with my proposed 
change:

struct GenericBox {
// Currently Swift resolves this as ‘GenericBox’
// With the new rule, we cannot infer the parameter, because there’s no 
expression to infer it from
func combine(other: GenericBox) {
…
}
}

Basically the meaning of ‘GenericBox’ right now depends on whether it appears 
inside its own definition or extension thereof, or not. The behavior when it 
appears elsewhere is more general — we infer the parameters from the 
surrounding expression, instead of assuming they’re equal to the context 
parameters.

This is a subtle change — definitely let me know if I’m not explaining it well.

Slava

> On Thu, Jun 23, 2016 at 15:14 Slava Pestov via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> Simpler interpretation of a reference to a generic type with no arguments
> 
> Proposal: SE- 
> <https://github.com/slavapestov/swift-evolution/blob/silly-proposals/proposals/-simplify-unbound-generic-type.md>
> Author: Slava Pestov <https://github.com/slavapestov>
> Status: Awaiting review
> Review manager: TBD
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#introduction>Introduction
> 
> This proposal cleans up the semantics of a reference to a generic type when 
> no generic arguments are applied.
> 
> Swift-evolution thread: Discussion thread topic for that proposal 
> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#motivation>Motivation
> 
> Right now, we allow a generic type to be referenced with no generic arguments 
> applied in a handful of special cases. The two primary rules here are the 
> following:
> 
> If the scope from which the reference is made is nested inside the definition 
> of the type or an extension thereof, omitting generic arguments just means to 
> implicitly apply the arguments from context.
> 
> For example,
> 
> struct GenericBox {
>   let contents: Contents
> 
>   // Equivalent to: func clone() -> GenericBox
>   func clone() -> GenericBox {
> return GenericBox(contents: contents)
>   }
> }
> 
> extension GenericBox {
>   func print() {
> // Equivalent to: let cloned: GenericBox
> let cloned: GenericBox = clone()
> print(cloned.contents)
>   }
> }
> If the type is referenced from an unrelated scope, we attempt to infer the 
> generic parameters.
> 
> For example,
> 
> func makeABox() -> GenericBox {
>   // Equivalent to: GenericBox(contents: 123)
>   return GenericBox(contents: 123)
> }
> The problem appears when the user expects the second behavior, but instead 
> encounters the first. For example, the following does not type check:
> 
> extension GenericBox {
> 
>   func transform(f: Contents -> T) -> GenericBox {
> // We resolve 'GenericBox' as 'GenericBox', rather than
> // inferring the type parameter
> return GenericBox(contents: f(contents))
>   }
> }
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#proposed-solution>Proposed
>  solution
> 
> The proposed solution is to remove the first rule altogether. If the generic 
> parameters cannot be inferred from context, they must be specified explicitly 
> with the usual Type syntax.
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#detailed-design>Detailed
>  design
> 
> This really just involves removing an existing piece of logic from the type 
> resolver code.
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#impact-on-existing-code>Impact
>  on existing code
> 
> This will have a small impact on existing code that uses a pattern similar to 
> the above.
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#alternatives-considered>Alternatives
>  considered
> 
>  
> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#status-quo>Status
>  quo
> 
> We could keep the current 

Re: [swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

2016-06-23 Thread Slava Pestov via swift-evolution

> On Jun 23, 2016, at 1:39 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Good to know. I absolutely agree that the gains to be had here wouldn't be 
> worth a one-off hack.

If people are strongly (or even mildly) opposed to removing this rule, we can 
give some thought to a more general solution. I don’t feel very strongly about 
this proposal one way or another, it’s just a bit of ugly code in 
TypeCheckType.cpp that would be nice to remove, and a developer on Twitter 
recently noticed this behavior and found it surprising.

> On Thu, Jun 23, 2016 at 15:36 Slava Pestov <spes...@apple.com 
> <mailto:spes...@apple.com>> wrote:
>> On Jun 23, 2016, at 1:34 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> Sorry, it's I who is saying things all wrong. I meant to ask, is it feasible 
>> to keep both behaviors but have #2 "win" over #1, instead of getting rid of 
>> behavior #1 entirely?
> 
> I suspect there might be some way, but I think it would have to be some kind 
> of one-off hack, which is not in line with our long-term goal of making the 
> type checker more maintainable and correct ‘by construction’.
> 
>> 
>> On Thu, Jun 23, 2016 at 15:30 Slava Pestov <spes...@apple.com 
>> <mailto:spes...@apple.com>> wrote:
>>> On Jun 23, 2016, at 1:27 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>> <mailto:xiaodi...@gmail.com>> wrote:
>>> 
>>> When you mention the difficulty of an alternative, is that to say that it's 
>>> not feasible for the GenericBox in the last example to be resolved as 
>>> GenericBox? From an end-user point of view, that seems to be the most 
>>> sensible behavior.
>> 
>> With my proposed change, GenericBox would be resolved as GenericBox in 
>> the last example. Right now it fails to type check.
>> 
>> Here is an example that works right now, but would not work with my proposed 
>> change:
>> 
>> struct GenericBox {
>>  // Currently Swift resolves this as ‘GenericBox’
>>  // With the new rule, we cannot infer the parameter, because there’s no 
>> expression to infer it from
>>  func combine(other: GenericBox) {
>>  …
>>  }
>> }
>> 
>> Basically the meaning of ‘GenericBox’ right now depends on whether it 
>> appears inside its own definition or extension thereof, or not. The behavior 
>> when it appears elsewhere is more general — we infer the parameters from the 
>> surrounding expression, instead of assuming they’re equal to the context 
>> parameters.
>> 
>> This is a subtle change — definitely let me know if I’m not explaining it 
>> well.
>> 
>> Slava
>> 
>>> On Thu, Jun 23, 2016 at 15:14 Slava Pestov via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> Simpler interpretation of a reference to a generic type with no arguments
>>> 
>>> Proposal: SE- 
>>> <https://github.com/slavapestov/swift-evolution/blob/silly-proposals/proposals/-simplify-unbound-generic-type.md>
>>> Author: Slava Pestov <https://github.com/slavapestov>
>>> Status: Awaiting review
>>> Review manager: TBD
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#introduction>Introduction
>>> 
>>> This proposal cleans up the semantics of a reference to a generic type when 
>>> no generic arguments are applied.
>>> 
>>> Swift-evolution thread: Discussion thread topic for that proposal 
>>> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>>>  
>>> <https://github.com/slavapestov/swift-evolution/tree/silly-proposals/proposals#motivation>Motivation
>>> 
>>> Right now, we allow a generic type to be referenced with no generic 
>>> arguments applied in a handful of special cases. The two primary rules here 
>>> are the following:
>>> 
>>> If the scope from which the reference is made is nested inside the 
>>> definition of the type or an extension thereof, omitting generic arguments 
>>> just means to implicitly apply the arguments from context.
>>> 
>>> For example,
>>> 
>>> struct GenericBox {
>>>   let contents: Contents
>>> 
>>>   // Equivalent to: func clone() -> GenericBox
>>>   func clone() -> GenericBox {
>>> return GenericBox(contents: contents)
>>>   }
>>> }
>>> 
>>> extension GenericBox 

Re: [swift-evolution] [Pitch] Make the formal type of 'self' consistent in class methods

2016-06-23 Thread Slava Pestov via swift-evolution
Great to hear some feedback so quickly, especially about something so mundane.

I suspect the real reason it doesn’t work this way now is that ‘Self’ is not 
fully plumbed through. In particular, if a closure captures the ‘Self’ type, 
IRGen does not properly codegen it, causing compile-time or run-time crashes:

class MyClass {
func foo(x: Int) -> Self {

// Crash!
_ = { print(self); print(x) }

return self
}

func bar(x: Int) -> MyClass {

// OK!
_ = { print(self); print(x) }

return self
}
}

Assertion failed: (LocalSelf && "no local self metadata"), function 
getLocalSelfMetadata, file /Users/slava/new/swift/lib/IRGen/GenType.cpp, line 
1805.
0  swift0x000114d5276e 
llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 46
1  swift0x000114d52c99 
PrintStackTraceSignalHandler(void*) + 25
2  swift0x000114d4efc9 llvm::sys::RunSignalHandlers() + 
425
3  swift0x000114d53312 SignalHandler(int) + 354
4  libsystem_platform.dylib 0x7fffc438a01a _sigtramp + 26
5  libsystem_platform.dylib 0x507ca710 _sigtramp + 2353268496
6  swift0x000114d52cbb raise + 27
7  swift0x000114d52d62 abort + 18
8  swift0x000114d52d4e __assert_rtn + 126
9  swift0x00010f6e8524 
swift::irgen::IRGenFunction::getLocalSelfMetadata() + 100

This comes up most frequently with the ‘weak self / strong self’ dance.

I’m going to fix this bug really soon, and it seems logical to deal with the 
language wart as well. We need the IRGen fix for SE-0086 as well in any case.

Slava

> On Jun 23, 2016, at 1:08 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> +1.  I have not encountered this issue myself but it looks like something 
> that would cause a lot of head scratching if I had.  It is also something 
> that I am unlikely to remember immediately if I run into it in the future.  
> The current behavior appears broken to me.  It will be great to have it fixed.
> 
>> On Jun 23, 2016, at 2:53 PM, Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Consistent formal type for 'self' in class methods
>> 
>> Proposal: SE- 
>> <https://github.com/slavapestov/swift-evolution/blob/self-formal-type-in-class/proposals/-self-formal-type-in-class.md>
>> Author: Slava Pestov <https://github.com/slavapestov>
>> Status: Awaiting review
>> Review manager: TBD
>> 
>>  
>> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#introduction>Introduction
>> 
>> This proposal makes the self value behave consistently whether or not it is 
>> used from a method with a Self return type.
>> 
>> Swift-evolution thread: Discussion thread topic for that proposal 
>> <http://news.gmane.org/gmane.comp.lang.swift.evolution>
>>  
>> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#motivation>Motivation
>> 
>> Right now, we exhibit inconsistent behavior when self is used as an argument 
>> to a generic function, violating the principle of least surprise.
>> 
>> Consider the following code:
>> 
>> class Base {
>>   @discardableResult
>>   func methodWithDynamicSelf() -> Self {
>> doSomething(self)
>> return self
>>   }
>> 
>>   func methodWithoutDynamicSelf() {
>> doSomething(self)
>>   }
>> }
>> 
>> class Derived : Base {}
>> 
>> func doSomething(_ t: T) {
>>   print(T.self)
>> }
>> 
>> Base().methodWithDynamicSelf()
>> Base().methodWithoutDynamicSelf()
>> 
>> Derived().methodWithDynamicSelf()
>> Derived().methodWithoutDynamicSelf()
>> Currently, it prints the following output:
>> 
>> Base
>> Base
>> Derived
>> Base
>> Note that there's no inconsistency when the method is called on the base 
>> class. When called on the derived class however, we see that in a method 
>> with a dynamic Self return type, the type of self is Derived, whereas in a 
>> method with any other return type, the type of self is Base.
>> 
>> 
>>  
>> <https://github.com/slavapestov/swift-evolution/tree/self-formal-type-in-class#proposed-solution>Proposed
>>  solution
>> 
>> The proposal is to change the type of self to always be Self, which can be 
>> thought of as a special generic type parameter bound to the dynamic type of 
>> the ins

Re: [swift-evolution] [Idea] Passing an Array to Variadic Functions

2016-04-20 Thread Slava Pestov via swift-evolution

> On Apr 19, 2016, at 10:54 AM, Haravikk via swift-evolution 
>  wrote:
> Possibly optimisations unavailable to Array passing?

Indeed, it should be possible to implement varargs by allocating the argument 
array on the stack (and having the compiler implicitly copy it to the heap 
inside the callee if it escapes). Although you can imagine this type of 
optimization being performed for arbitrary arrays, it would be more difficult 
and less predictable.

Slava

> 
> Cons:
> Doesn’t do anything that passing an array directly can’t.
> Passing an array is actually slightly more flexible (can dynamically pass 
> more or less arguments as required at the call site).
> Less explicit type at call site; gives the appearance of passing instance(s) 
> of Foo, rather than one instance of [Foo], can lead to ambiguity with 
> overloaded functions.
> Extra syntax to support (enabling array passing would be more code required 
> to support this feature)
> 
> I’d also argue that variadic functions increase the learning curve, as the 
> first time you’re presented with one it isn’t necessarily clear what it does 
> unless you’ve encountered them before. Like I say it can be ambiguous at the 
> call-site in particular, as it doesn’t show that an array of [Foo] is being 
> passed as opposed to N instances of Foo (however many are in the call).
> 
> While I’ve used them in the past, I’ve never really felt that they simplify 
> anything enough to justify them, as it’s just two square brackets extra to 
> pass an array; this is extra noise sure, but clarifies what is actually 
> happening.
> 
> So if variadic functions don’t have any other advantages, then it’s really 
> just a very minor piece of syntactic sugar that can lead to more confusion, 
> less explicit types in function calls, an extra piece of syntax to parse and 
> handle and possibly other features required to support it better (like the 
> one being inquired about). The only other argument I can think of for them is 
> that many other languages have them, but that’s not important to me vs 
> cutting out cruft.
> 
> 
> Short version; removing variadic functions would solve the problem of 
> defining overloads for both variadic and array types by only ever requiring 
> the latter.
> 
> P.S- I’d also like to note that where possible people should be accepting 
> Sequences or Collections in their methods anyway rather than arrays 
> specifically, as it’s more flexible that way ;)
> ___
> 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] [swift-dev] End of source-breaking changes for Swift 3

2016-07-27 Thread Slava Pestov via swift-evolution

> On Jul 27, 2016, at 12:38 PM, Ted Kremenek via swift-dev 
>  wrote:
> 
> 
> SE-0092 - Typealiases in protocols and protocol extensions 
> 
> SE-0102 - Remove @noreturn attribute and introduce an empty Never type 
> 
These two are implemented. Should I prepare a PR to update the proposals?

Slava

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


Re: [swift-evolution] What're the Swift team's thoughts on Go's concurrency?

2016-08-11 Thread Slava Pestov via swift-evolution

> On Aug 11, 2016, at 11:47 AM, Goffredo Marocchi via swift-evolution 
>  wrote:
> 
> Thanks for the concise and clear review of green threads :). I can understand 
> the concerns of runtime implementation when the runtime of the language is 
> replacing the kernel scheduler.
> 
> Sent from my iPhone

One interesting thing that you can do to get around the limitations is to run 
blocking system calls in their own special thread pool off to the side. This is 
how node.js deals with blocking I/O I believe. However this seems like it would 
add a lot of overhead, and it’s probably not a direction we want to go in with 
Swift. Of course nothing prevents users from developing their own thread pool 
libraries, if they so choose. Even coroutines would not be too difficult to do 
with Swift, since we don’t do anything funny with the callstack. So the usual 
tricks should work.

Slava

> 
> On 11 Aug 2016, at 19:09, Kevin Ballard > 
> wrote:
> 
>> AIUI, fibers are basically coroutines. Even the Naughty Dog presentation 
>> says that fibers are run on threads, and you have to make an explicit call 
>> to switch between fibers. Looking at Ruby's Fiber type, that's also an 
>> explicit coroutine, where you actually yield up a value when you yield your 
>> fiber (which is exactly what coroutines do).
>> 
>> So basically, green threading is preemptive multithreading where the 
>> preempting is done in user-space by the runtime (so it only happens at 
>> specific points where your code calls back into the runtime, but it can 
>> happen at any of those points), and multiple green threads get scheduled 
>> onto the same OS thread, whereas fibers is cooperative multithreading where 
>> your code explicitly yields back to the runtime to switch fibers.
>> 
>> Of course I could be wrong, but that's the impression I got after reading a 
>> few different things about Fibers.
>> 
>> -Kevin
>> 
>> On Thu, Aug 11, 2016, at 10:54 AM, Goffredo Marocchi wrote:
>>> Hello Kevin,
>>> I may be wrong in my equating support for fibers to green threads (and the 
>>> runtime cost of supporting them), but I do have seen and linked to a 
>>> presentation of the use and more than trivial benefits to Naughty Dog's 
>>> engine in utilising the 8 Jaguar x86 cores in the PlayStation 4 CPU. 
>>> Although like you said, it did not come for free or without evident pain 
>>> points for them.
>>> 
>>> On Thu, Aug 11, 2016 at 6:50 PM, Kevin Ballard >> > wrote:
>>> 
>>> I'm confused by your email. Rust is all about performance, and embedded 
>>> devices are one of the targets for Rust. And I can't think of any language 
>>> that uses green threading that is appropriate for constrained devices (e.g. 
>>> Go definitely isn't appropriate for that). One of the arguments for getting 
>>> rid of green threading in Rust is that the extra runtime complexity imposed 
>>> a performance cost.
>>> 
>>> 
>>> -Kevin
>>> 
>>> 
>>> On Thu, Aug 11, 2016, at 10:36 AM, Goffredo Marocchi wrote:
 Thanks Kevin, I think they have accepted that they do not need to enter 
 every segment of computing so the extra performance they could get on some 
 devices is not worth the risk and the complexity it brings. Not everyone 
 is trying to cram complex 3D experiences at 60-90+ FPS on a console like 
 constrained devices and I guess Rust is not targeting that right now :).
 
 On Thu, Aug 11, 2016 at 6:12 PM, Kevin Ballard via swift-evolution 
 > wrote:
 For anyone interested in reading more about Rust's decisions, here's two 
 links:
 
 The email about abandoning segmented stacks: 
 https://mail.mozilla.org/pipermail/rust-dev/2013-November/006314.html 
 
 
 The RFC to remove green threading, with motivation: 
 https://github.com/aturon/rfcs/blob/remove-runtime/active/-remove-runtime.md
  
 
 
 -Kevin Ballard
 
 
 On Tue, Aug 9, 2016, at 01:28 PM, Kevin Ballard wrote:
 > The Rust language used to use a green thread model like Go (actually it 
 > exposed a configurable threading interface so you could choose green 
 > threads or OS threads). It also used segmented stacks like Go did. Over 
 > time, Rust ended up dropping the segmented stacks because it 
 > significantly complicated FFI without providing much, if any, benefit 
 > (and IIRC Go followed suite and dropped segmented stacks somewhere 
 > around version 1.5), and then a little while later Rust dropped green 
 > threads entirely. If you can find them, there are lots of discussions of 
 > the pros and cons that were documented during this process (on mailing 
 > lists, in IRC, 

Re: [swift-evolution] ABI in Layman's terms?

2016-08-11 Thread Slava Pestov via swift-evolution

> On Aug 11, 2016, at 4:27 AM, David Hart via swift-evolution 
>  wrote:
> 
> I'd also like to understand this more and this answer does not completely 
> satisfy me. I understand backwards compatibility, especially in terms of 
> source breaking changes.
> 
> I have more difficulties understanding what breaks or not the ABI and how to 
> make educated guesses about what features will require breaking it

This is hard to explain right now without detailed knowledge of IRGen and 
SILGen internals. However we are planning on relaxing the restrictions as much 
as possible, so that source-compatible changes remain binary compatible. For 
example, we would like to be able to add new fields to structs, change computed 
properties to stored and vice versa, insert new classes in a hierarchy, add 
cases to enums, and so on. This falls under the umbrella of "resilience".

Here's a document outlining what will be ABI compatible and what will not -- 
keep in mind that a good chunk of this is not yet implemented:

https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst

> 
> On 11 Aug 2016, at 13:24, Anton Zhilin via swift-evolution 
> > wrote:
> 
>> 2016-08-11 11:52 GMT+03:00 Jonathan Hull via swift-evolution 
>> >:
>> Could someone explain in simple terms what the ABI is and what sorts of 
>> things might affect it?
>> 
>> I had thought it was the layout in memory of structs/classes/etc… and how 
>> the program knows where to go to find a particular field.  This seems to be 
>> incorrect though, as I have seen many features that I would assume have some 
>> affect on this layout ruled “out of scope for phase 1”.  For example, I 
>> would think that many generics features would have an impact on the ABI, or 
>> the idea of COW (via secret boxing) for structs, or even union types.
>> 
>> At the very least, I would think that mix-ins would have a fairly 
>> significant effect.
>> 
>> ABI stability means that changes will have to be backwards compatible after 
>> a certain stage. If we can add mixins feature without modifying old code 
>> (and its SIL and IR and whatever), then we are fine. 
>> ___
>> 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] ABI in Layman's terms?

2016-08-11 Thread Slava Pestov via swift-evolution

> On Aug 11, 2016, at 1:48 PM, Slava Pestov via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> 
>> On Aug 11, 2016, at 4:27 AM, David Hart via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I'd also like to understand this more and this answer does not completely 
>> satisfy me. I understand backwards compatibility, especially in terms of 
>> source breaking changes.
>> 
>> I have more difficulties understanding what breaks or not the ABI and how to 
>> make educated guesses about what features will require breaking it
> 
> This is hard to explain right now without detailed knowledge of IRGen and 
> SILGen internals. However we are planning on relaxing the restrictions as 
> much as possible, so that source-compatible changes remain binary compatible. 
> For example, we would like to be able to add new fields to structs, change 
> computed properties to stored and vice versa, insert new classes in a 
> hierarchy, add cases to enums, and so on. This falls under the umbrella of 
> "resilience".
> 
> Here's a document outlining what will be ABI compatible and what will not -- 
> keep in mind that a good chunk of this is not yet implemented:
> 
> https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst 
> <https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst>
As a follow-up explanation, when we talk about the ABI, we're really talking 
about three orthogonal "axes" along which we would like to "move" without 
breaking compatibility with existing binaries:

- The first axis is the machine-level calling conventions and memory layout. 
For example, what registers to pass function arguments and returns in, the 
rules for alignment and padding of fields in an aggregate type, which entry 
points the Swift runtime exports and what their behavior should be. Once we 
commit to a stable ABI along this axis, you will get interoperability between 
*compiler versions* -- the same exact library built with one version of the 
compiler will remain compatible with clients after being recompiled with 
another version, because their conventions will match up. Note that this does 
not help you if the library itself changes in any way.

- The second axis is the resilience work I called out in my previous e-mail. 
Here, we're trying to define language features and implementation techniques 
that allow a library to evolve in a forward-compatible manner, as long as the 
developer follows certain guidelines. Here, the goal is if you should be able 
to compile your library, make some changes to add new APIs, and recompile it 
*with the same compiler*, without breaking downstream clients, as long as you 
follow the library evolution guidelines (Also, you can imagine one day having 
an 'ABI diff' tool to automate this).

- The third axis is the standard library itself. Stability of runtime 
interfaces and the extra indirection to enable resilience is all great, but it 
won't help you as long as the standard library API is evolving in a 
non-backwards compatible manner -- for example, if we remove a method on 
String. So once the other two areas have been addressed, the last thing to lock 
down is the standard library interface itself.

> 
>> 
>> On 11 Aug 2016, at 13:24, Anton Zhilin via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 2016-08-11 11:52 GMT+03:00 Jonathan Hull via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>:
>>> Could someone explain in simple terms what the ABI is and what sorts of 
>>> things might affect it?
>>> 
>>> I had thought it was the layout in memory of structs/classes/etc… and how 
>>> the program knows where to go to find a particular field.  This seems to be 
>>> incorrect though, as I have seen many features that I would assume have 
>>> some affect on this layout ruled “out of scope for phase 1”.  For example, 
>>> I would think that many generics features would have an impact on the ABI, 
>>> or the idea of COW (via secret boxing) for structs, or even union types.
>>> 
>>> At the very least, I would think that mix-ins would have a fairly 
>>> significant effect.
>>> 
>>> ABI stability means that changes will have to be backwards compatible after 
>>> a certain stage. If we can add mixins feature without modifying old code 
>>> (and its SIL and IR and whatever), then we are fine. 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift

Re: [swift-evolution] [Pitch] Rename Mirror

2016-08-10 Thread Slava Pestov via swift-evolution

> On Jul 21, 2016, at 4:06 PM, Anton Zhilin via swift-evolution 
>  wrote:
> 
> 2016-07-22 1:34 GMT+03:00 Dmitri Gribenko  >:
> > Mirror.DisplayStyle contains optional and set as special cases, but does not
> > contain function
> > Mirror collects all information possible at initialization, while for true
> > reflection we want laziness
> > Mirror allows customization. For example, Array is represented with a
> > field for each of its elements. Do we want this for “true” reflection we
> > want to add in the future?
> 
> Why can't we add these features to Mirror in future?
> 
> Reflection in some other languages works as follows: we have a type (let's 
> name it 'Reflection'). Each instance of it contains ID of one type and can, 
> for example, retrieve an array of its static or normal methods.
> 'Mirror', on the other hand, serves as a container for information about a 
> single instance. Moreover, types can completely customize contents of their 
> 'Mirror's. This is incompatible with laziness and with how reflection should 
> work, based on experience from other languages.

I think pointing a Mirror at a metatype value could be a good a mechanism for 
getting information about the type's stored properties and other members.

FWIW Mirrors are inspired by a feature of the same name in the Self language, 
which made reflection somewhat more principled than the disorganized APIs you 
see in Java and C#. Perhaps the latter are not a good model to follow here :-)

Slava


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


Re: [swift-evolution] What're the Swift team's thoughts on Go's concurrency?

2016-08-10 Thread Slava Pestov via swift-evolution

> On Aug 9, 2016, at 1:59 PM, Joe Groff via swift-evolution 
>  wrote:
> 
>> 
>> On Aug 9, 2016, at 1:28 PM, Kevin Ballard via swift-evolution 
>>  wrote:
>> 
>> The Rust language used to use a green thread model like Go (actually it 
>> exposed a configurable threading interface so you could choose green threads 
>> or OS threads). It also used segmented stacks like Go did. Over time, Rust 
>> ended up dropping the segmented stacks because it significantly complicated 
>> FFI without providing much, if any, benefit (and IIRC Go followed suite and 
>> dropped segmented stacks somewhere around version 1.5), and then a little 
>> while later Rust dropped green threads entirely. If you can find them, there 
>> are lots of discussions of the pros and cons that were documented during 
>> this process (on mailing lists, in IRC, possibly on Discourse, there's 
>> probably at least one post about it in the Rust subreddit, etc). But 
>> ultimately, it was determined that keeping this ability significantly 
>> complicated the Rust runtime and it provided almost no benefit. The OS is 
>> already really good at scheduling threads, and there's no memory savings 
>> without segmented stacks (though the OS will map virtual pages for the stack 
>> and only allocate the backing physical pages as the memory is touched, so 
>> even if you have a 2MB stack, a new thread will only actually allocate 
>> something like 8kb). And there are some pretty big downsides to green 
>> threads, such as the fact that it significantly complicates the runtime 
>> since all I/O everywhere has to be nonblocking and it has to be transparent 
>> to the code, and FFI ends up as a major problem (even without segmented 
>> stacks), because you have no idea if an FFI call will block. Green threading 
>> libraries end up having to allocate extra OS threads just to continue 
>> servicing the green threads when the existing threads are potentially 
>> blocked in FFI.
>> 
>> So ultimately, green threads really only make sense when you control the 
>> entire ecosystem, so you can ensure the whole stack is compatible with green 
>> threads and won't ever issue blocking calls, and even there there's not much 
>> benefit and there's a lot of complexity involved.
> 
> In addition to FFI, there's also no way for memory-mapped IO to be 
> non-blocking (a page fault can only be handled by the kernel, after all).

Even buffered file I/O via read(2) and write(2) is blocking on most *nix 
platforms. AFAIK there's some work being done on non-blocking buffered reads on 
Linux, but it appears to be a completely new API distinct from the existing 
epoll for sockets or aio_* for direct file I/O, and of course Darwin doesn't 
have an equivalent.

Slava

> 
> -Joe
> ___
> 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] What're the Swift team's thoughts on Go's concurrency?

2016-08-10 Thread Slava Pestov via swift-evolution

> On Aug 10, 2016, at 3:22 PM, David Sweeris <daveswee...@mac.com> wrote:
> 
>> On Aug 10, 2016, at 4:48 PM, Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> As I understand it, a big weakness of Go's model is that it does not 
>> actually prevent data races. There's nothing preventing you from sharing 
>> pointers to mutable values between tasks, but I could be wrong about this.
> Is that bad? Sharing pointers seems like a cheap way to share data, and as 
> long as you know what you’re doing, why should the language get in the way? 
> Now, if said code really does have performance advantages over the “safer” 
> methods, and it really is safe because for whatever reason the race condition 
> can’t actually happen, the language (or library) ought to have a way to 
> express that without having to write “unsafe” code. In the meantime, though, 
> you’ve gotta ship something that runs and meets performance requirements.

Well, ideally, the type system would be able to enforce that values passed 
across thread boundaries are immutable. Rust's model allows this, I believe.

The possibility of mutating shared state in an unprincipled manner is "bad" in 
the same sense that being able to call free() in C is "bad" -- it's an 
abstraction violation if you get it wrong. Compared to languages with automatic 
memory management, there are advantages (control over memory management) and 
disadvantages (fewer static guarantees).


> 
> - Dave Sweeris

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


Re: [swift-evolution] What're the Swift team's thoughts on Go's concurrency?

2016-08-10 Thread Slava Pestov via swift-evolution

> On Aug 10, 2016, at 3:34 PM, Christopher Kornher <ckorn...@me.com> wrote:
> 
> Would this prevent an object from being “known" to multiple threads? 
> …multiple queues? If so, it would be overly restrictive for a general-purpose 
> language. I assume that the plan includes a way to allow “unsafe” behavior to 
> support other concurrency models.
> 

To be clear I'm not presenting any ideas for Swift here, just critiquing Go's 
model.

Yes, I'm just talking about 'safe' language features for passing immutable data 
between threads. This would not preclude other forms of concurrency from 
existing in the language, such as locks, atomics, etc. But I think if a user 
writes code with only message passing, the language should ensure that the 
result is free from data races. Go does not do that, which is unfortunate.

Slava

> 
>> On Aug 10, 2016, at 4:24 PM, Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> 
>>> On Aug 10, 2016, at 3:22 PM, David Sweeris <daveswee...@mac.com> wrote:
>>> 
>>>> On Aug 10, 2016, at 4:48 PM, Slava Pestov via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> As I understand it, a big weakness of Go's model is that it does not 
>>>> actually prevent data races. There's nothing preventing you from sharing 
>>>> pointers to mutable values between tasks, but I could be wrong about this.
>>> Is that bad? Sharing pointers seems like a cheap way to share data, and as 
>>> long as you know what you’re doing, why should the language get in the way? 
>>> Now, if said code really does have performance advantages over the “safer” 
>>> methods, and it really is safe because for whatever reason the race 
>>> condition can’t actually happen, the language (or library) ought to have a 
>>> way to express that without having to write “unsafe” code. In the meantime, 
>>> though, you’ve gotta ship something that runs and meets performance 
>>> requirements.
>> 
>> Well, ideally, the type system would be able to enforce that values passed 
>> across thread boundaries are immutable. Rust's model allows this, I believe.
>> 
>> The possibility of mutating shared state in an unprincipled manner is "bad" 
>> in the same sense that being able to call free() in C is "bad" -- it's an 
>> abstraction violation if you get it wrong. Compared to languages with 
>> automatic memory management, there are advantages (control over memory 
>> management) and disadvantages (fewer static guarantees).
>> 
>> 
>>> 
>>> - Dave Sweeris
>> 
>> ___
>> 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: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution
-1 — this adds a new syntax with little gain, and potentially a lot of 
additional complexity.

> On Aug 16, 2016, at 2:49 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
> Unfortunately, when this has come up on the list in the past, it has been 
> mentioned that there are some cases where an existential of a protocol does 
> not conform to the protocol itself, so it is impossible to make : always 
> match items that are typed to the protocol.

Indeed, the best solution IMHO would be to implement self-conforming protocols, 
so that what you’re describing can be expressed without any additional syntax.

The condition for a protocol to be able to conform to itself is the following:

- it must not have any associated type requirements, or contravariant Self in 
requirement signatures; eg, this rules out the following:

  protocol P { func foo(s: Self) }

- it must not have any static method or initializer requirements

With these conditions met, it would be possible to allow a generic parameter ’T 
: P’ to bind to a concrete type ’P’.

Note that the type checker work required for this is not very difficult. 
Indeed, we already allow @objc protocols that don’t have static requirements to 
self-conform. The real issue is the runtime representation gets tricky, if you 
want to allow a generic parameter to contain both a concrete type conforming to 
P, and an existential of P. Basically a generic parameter is passed as three 
values behind the scenes, the actual value, type metadata for the concrete 
type, and a witness table for the conformance. To allow the parameter to be 
bound to an existential type we would need to pass in a special witness table 
that unpacks the existential and calls the witness table contained in the 
existential.

It’s even worse if the protocol that self-conforms is a class-bound protocol. A 
generic parameter conforming to a class-bound protocol is passed as a reference 
counted pointer and witness table. Unfortunately, a class-bound existential is 
*not* a reference counted pointer — it has the witness table ‘inside’ the value.

Probably my explanation isn’t great, but really what’s bothering you here isn’t 
a language limitation, it’s an implementation limitation — once we figure out 
how to represent protocol existentials efficiently in a way allowing them to 
self-conform, we should be able to address these use-cases without new syntax.

Cheers,

Slava

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


Re: [swift-evolution] PITCH: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 16, 2016, at 6:05 PM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> On Aug 16, 2016, at 7:48 PM, Xiaodi Wu > > wrote:
>> 
>> On Tue, Aug 16, 2016 at 7:43 PM, Charles Srstka > > wrote:
>>> On Aug 16, 2016, at 7:08 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Tue, Aug 16, 2016 at 6:59 PM, Karl >> > wrote:
>>> 
 On 17 Aug 2016, at 00:34, Charles Srstka via swift-evolution 
 > wrote:
 
> On Aug 16, 2016, at 5:30 PM, Xiaodi Wu  > wrote:
> 
> On Tue, Aug 16, 2016 at 5:19 PM, Charles Srstka via swift-evolution 
> > wrote:
>> On Aug 16, 2016, at 5:13 PM, David Sweeris > > wrote:
>> 
>> Any proposal that expands the power of generic programming gets an 
>> almost automatic +1 from me.
>> 
>> I can't think of any circumstances in which I wouldn't want to use ":==" 
>> instead of ":". Are there any downsides to expanding ":" to mean what 
>> ":==" does?
>> 
>> Incidentally, I kinda thought things either already worked like this, or 
>> would work like this after generics were "completed", but I can't tell 
>> you why I thought that.
> 
> Me neither, but the last time I proposed that, people stated that there 
> were some cases where this could not work. No concrete examples were 
> given, but I assume it probably has something to do with associated type 
> wackiness. :== seems like a workable compromise to me.
> 
> If an existential of a protocol P doesn't conform to itself, what can you 
> do inside the body of a generic function that has a generic constraint 
> specified with `:==`? In other words, what would we know about what's in 
> common between such an existential of a protocol and types that conform 
> to the protocol?
 
 My proposal is that in such cases, using :== would lead to a compiler 
 error.
 
 Charles
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org 
 https://lists.swift.org/mailman/listinfo/swift-evolution 
 
>>> I think the point is that existentials not conforming to their protocols is 
>>> the underlying reason this doesn’t work already.
>>> 
>>> From the previous thread:
 There are a couple of reasons this is the case.  IIRC in some cases it 
 actually isn't possible for the existential to conform to the protocol in 
 a sound way.  And even when it is possible, I believe it has been said 
 that it is more difficult to implement than you might think.  Hopefully 
 the situation will improve in the future but I'm not aware of any specific 
 plans at the moment.
>>> 
>>> It seems like a reasonably straightforward axiom. I would be interested to 
>>> learn more about those edge-cases.
>>> 
>>> Hmm, re-reading that makes me worry about this proposal at a practical 
>>> level. IIUC, this is something that is pretty much desired across the 
>>> board, and if we could have it for `:` it'd be best.
>>> But, it sounds like the reason `:` doesn't work that way isn't that the 
>>> core team has a different opinion, but rather that it's very difficult to 
>>> implement. And, IIUC, the situation is that no protocol existential 
>>> currently conforms to itself, not that some do and some don't. The 
>>> implementation work wouldn't be any easier if we called the operator 
>>> `:==`...
>> 
>> 
>> There are various ways to work around the problem using a new operator, 
>> though, depending on how much work you wanted to do in implementing it. At 
>> the very least you could take the ‘preprocessor’ approach and turn one 
>> function using :== into two separate functions, one using == and one using 
>> :, with both functions sharing the same body. This would still have the code 
>> bloat in the binary, but at least it wouldn’t be bloating up the source. We 
>> could then solve some of the binary bloat by spinning off the function body 
>> into a third function and having both the two original functions call that. 
>> Or maybe we could have the : variant reinterpret the sequence as an == 
>> sequence and send it to the == variant. There are multiple ways that this 
>> could be handled without forcing protocols to conform to themselves.
>> 
>> Not an expert, but wouldn't this blow up a whole bunch of compile-time 
>> "stuff" like the type checker? If no protocol existential conforms to 
>> itself, and it's 

Re: [swift-evolution] PITCH: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 16, 2016, at 6:40 PM, Charles Srstka  wrote:
> 
>> On Aug 16, 2016, at 8:13 PM, Slava Pestov > > wrote:
>> 
>> -1 — this adds a new syntax with little gain, and potentially a lot of 
>> additional complexity.
>> 
>>> On Aug 16, 2016, at 2:49 PM, Charles Srstka via swift-evolution 
>>> > wrote:
>>> 
>>> Unfortunately, when this has come up on the list in the past, it has been 
>>> mentioned that there are some cases where an existential of a protocol does 
>>> not conform to the protocol itself, so it is impossible to make : always 
>>> match items that are typed to the protocol.
>> 
>> Indeed, the best solution IMHO would be to implement self-conforming 
>> protocols, so that what you’re describing can be expressed without any 
>> additional syntax.
>> 
>> The condition for a protocol to be able to conform to itself is the 
>> following:
>> 
>> - it must not have any associated type requirements, or contravariant Self 
>> in requirement signatures; eg, this rules out the following:
>> 
>>  protocol P { func foo(s: Self) }
>> 
>> - it must not have any static method or initializer requirements
>> 
>> With these conditions met, it would be possible to allow a generic parameter 
>> ’T : P’ to bind to a concrete type ’P’.
> 
> Well if it can be done, then that’s great. The reason I thought of a new 
> modifier is because the last time I suggested extending : to include the 
> protocol itself, the reaction was quite negative, suggesting that the amount 
> of work necessary to do that would be outside the bounds of what could be 
> considered reasonable.

The amount of work is certainly not trivial, but this feature request comes up 
often enough that I think we should try to tackle it at some point.

> I am a little concerned about the second requirement. Protocols that include 
> static methods and initializers work perfectly well inside arrays, and 
> restricting them from generic collections will further discourage use of the 
> latter in favor of the former.

Here is why we must have that requirement. Consider the following code:

protocol P {
  init()
}

struct A : P {
  init() {}
}

struct B : P {
  init() {}
}

func makeIt() -> T {
  return T()
}

I can use this function as follows:

let a: A = makeIt() // Creates a new ‘A'
let a: B = makeIt() // Creates a new ‘B’

Now suppose we allow P to self-conform. Then the following becomes valid:

let p: P = makeIt()

What exactly would makeIt() do in this case? There’s no concrete type passed 
in, or any way of getting one, so there’s nothing to construct. The same issue 
would come up with static methods here.


> 
>> Note that the type checker work required for this is not very difficult. 
>> Indeed, we already allow @objc protocols that don’t have static requirements 
>> to self-conform. The real issue is the runtime representation gets tricky, 
>> if you want to allow a generic parameter to contain both a concrete type 
>> conforming to P, and an existential of P. Basically a generic parameter is 
>> passed as three values behind the scenes, the actual value, type metadata 
>> for the concrete type, and a witness table for the conformance. To allow the 
>> parameter to be bound to an existential type we would need to pass in a 
>> special witness table that unpacks the existential and calls the witness 
>> table contained in the existential.
>> 
>> It’s even worse if the protocol that self-conforms is a class-bound 
>> protocol. A generic parameter conforming to a class-bound protocol is passed 
>> as a reference counted pointer and witness table. Unfortunately, a 
>> class-bound existential is *not* a reference counted pointer — it has the 
>> witness table ‘inside’ the value.
>> 
>> Probably my explanation isn’t great, but really what’s bothering you here 
>> isn’t a language limitation, it’s an implementation limitation — once we 
>> figure out how to represent protocol existentials efficiently in a way 
>> allowing them to self-conform, we should be able to address these use-cases 
>> without new syntax.
> 
> What I’ve long wondered is why we don’t have this problem with arrays.
> 
> protocol MyProto {
> func baz()
> 
> // Includes static and initializer requirements
> static func qux()
> init()
> }
> 
> struct MyStruct: MyProto {
> func baz() {
> print("baz")
> }
> 
> static func qux() {
> print("qux")
> }
> 
> init() {
> print("init")
> }
> }
> 
> func foo(bar: [MyProto]) {
> for eachMyProto in bar {
> eachMyProto.baz()
> }
> }
> 
> let x = [MyStruct()]
> let y = x as [MyProto]
> 
> foo(bar: x)
> foo(bar: y)
> 
> This compiles and runs fine. Why is that?

Recall that an Array is just a (very complex) generic struct in Swift:

struct Array {
  …
}

The key here is that there are *no generic requirements* placed on the 

Re: [swift-evolution] PITCH: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 16, 2016, at 6:51 PM, Slava Pestov  wrote:
> 
>> 
>> On Aug 16, 2016, at 6:40 PM, Charles Srstka > > wrote:
>> 
>>> On Aug 16, 2016, at 8:13 PM, Slava Pestov >> > wrote:
>>> 
>>> -1 — this adds a new syntax with little gain, and potentially a lot of 
>>> additional complexity.
>>> 
 On Aug 16, 2016, at 2:49 PM, Charles Srstka via swift-evolution 
 > wrote:
 
 Unfortunately, when this has come up on the list in the past, it has been 
 mentioned that there are some cases where an existential of a protocol 
 does not conform to the protocol itself, so it is impossible to make : 
 always match items that are typed to the protocol.
>>> 
>>> Indeed, the best solution IMHO would be to implement self-conforming 
>>> protocols, so that what you’re describing can be expressed without any 
>>> additional syntax.
>>> 
>>> The condition for a protocol to be able to conform to itself is the 
>>> following:
>>> 
>>> - it must not have any associated type requirements, or contravariant Self 
>>> in requirement signatures; eg, this rules out the following:
>>> 
>>>  protocol P { func foo(s: Self) }
>>> 
>>> - it must not have any static method or initializer requirements
>>> 
>>> With these conditions met, it would be possible to allow a generic 
>>> parameter ’T : P’ to bind to a concrete type ’P’.
>> 
>> Well if it can be done, then that’s great. The reason I thought of a new 
>> modifier is because the last time I suggested extending : to include the 
>> protocol itself, the reaction was quite negative, suggesting that the amount 
>> of work necessary to do that would be outside the bounds of what could be 
>> considered reasonable.
> 
> The amount of work is certainly not trivial, but this feature request comes 
> up often enough that I think we should try to tackle it at some point.
> 
>> I am a little concerned about the second requirement. Protocols that include 
>> static methods and initializers work perfectly well inside arrays, and 
>> restricting them from generic collections will further discourage use of the 
>> latter in favor of the former.
> 
> Here is why we must have that requirement. Consider the following code:
> 
> protocol P {
>   init()
> }
> 
> struct A : P {
>   init() {}
> }
> 
> struct B : P {
>   init() {}
> }
> 
> func makeIt() -> T {
>   return T()
> }
> 
> I can use this function as follows:
> 
> let a: A = makeIt() // Creates a new ‘A'
> let a: B = makeIt() // Creates a new ‘B’
> 
> Now suppose we allow P to self-conform. Then the following becomes valid:
> 
> let p: P = makeIt()
> 
> What exactly would makeIt() do in this case? There’s no concrete type passed 
> in, or any way of getting one, so there’s nothing to construct. The same 
> issue would come up with static methods here.

Yeah, so I should add one way around this is to factor your protocol into two — 
Q can be a self-conforming base protocol, and P can refine Q with additional 
requirements such as initializers. This means that forming a type Array and 
passing it around is totally fine; you just can’t pass an Array to a 
function with type  Array -> …, because P cannot bind to . 
You’d be able to pass an Array to a functio nwith type  Array -> … 
though — the substitution T := P would be permitted in this case, since there 
are no static requirements visible on ’T’.

Slava

> 
> 
>> 
>>> Note that the type checker work required for this is not very difficult. 
>>> Indeed, we already allow @objc protocols that don’t have static 
>>> requirements to self-conform. The real issue is the runtime representation 
>>> gets tricky, if you want to allow a generic parameter to contain both a 
>>> concrete type conforming to P, and an existential of P. Basically a generic 
>>> parameter is passed as three values behind the scenes, the actual value, 
>>> type metadata for the concrete type, and a witness table for the 
>>> conformance. To allow the parameter to be bound to an existential type we 
>>> would need to pass in a special witness table that unpacks the existential 
>>> and calls the witness table contained in the existential.
>>> 
>>> It’s even worse if the protocol that self-conforms is a class-bound 
>>> protocol. A generic parameter conforming to a class-bound protocol is 
>>> passed as a reference counted pointer and witness table. Unfortunately, a 
>>> class-bound existential is *not* a reference counted pointer — it has the 
>>> witness table ‘inside’ the value.
>>> 
>>> Probably my explanation isn’t great, but really what’s bothering you here 
>>> isn’t a language limitation, it’s an implementation limitation — once we 
>>> figure out how to represent protocol existentials efficiently in a way 
>>> allowing them to self-conform, we should be able to address these use-cases 
>>> without new syntax.
>> 

Re: [swift-evolution] InternalString class for easy String manipulation

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 14, 2016, at 3:41 PM, Michael Savich via swift-evolution 
>  wrote:
> 
> What about having an InternalString subclass that only supports one encoding, 
> allowing it to be subscripted with Ints? The idea is that an InternalString 
> is for Strings that are more or less hard coded into the app. Dictionary 
> keys, enum raw values, that kind of stuff. This also has the added benefit of 
> forcing the programmer to think about what the String is being used for. Is 
> it user facing? Or is it just for internal use? And of course, it makes code 
> dealing with String manipulation much more concise and readable.

If you actually just want an ASCII string, you can just use an Array and 
avoid all the complexity of Unicode altogether. You won’t get the string 
literal syntax, but if you’re really adventurous you can wrap it in a new 
struct type, and define an ExpressibleByStringLiteral conformance.

Slava

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


Re: [swift-evolution] PITCH: New :== operator for generic constraints

2016-08-17 Thread Slava Pestov via swift-evolution

> On Aug 17, 2016, at 11:36 AM, Charles Srstka via swift-evolution 
>  wrote:
> 
>> On Aug 17, 2016, at 12:02 PM, Vladimir.S via swift-evolution 
>> > wrote:
>> 
>> On 17.08.2016 13:00, Boris Wang via swift-evolution wrote:
>>> The problem is that:
>>> protocol should not be a type, but it is a type sometime and not type
>>> sometime now.
>>> 
>>> for exam:
>>> P.Type not same as T.Type
>>> 
>>> But you can declare a variable of type P.
>>> 
>>> Protocol should be a contract only, no instances of it.
>> 
>> I'm also confused about this. Tried to follow the whole discussion of 
>> experienced(as I understand) developer Charles and a member of core team, 
>> and saw that even experienced developer had some troubles to understand all 
>> the catches of protocols in Swift.
>> 
>> How we want to make less experienced developers to understand Swift's model 
>> of protocols While problems begins 
>> with the most used Equatable/Hashable protocols..
>> 
>> Also I believe the syntax of generic constraints in 'where' part is 
>> confusing. I'm about this:
>> 
>> func pick(peppers: PepperType) where 
>> PepperType.Iterator.Element == Pepper
>> 
>> If '== Proto' means *exactly* typed as such protocol("let arr : [Proto] = 
>> .."), so IMO ': Proto' should means *typed* as exactly this protocol or any 
>> derived protocol("let arr : [ProtocolDerivedFromProto] = .."). Just in 
>> symmetry with class types in 'where' clause here.
>> 
>> Currently, how to specify 'protocol Proto or its derived protocols" ?
> 
> Basically, the issue is that as things currently stand, there is no way to 
> specify that. Your options basically boil down to: 1) implement the method 
> twice, 2) force the caller to cast to the protocol first, or 3) just use an 
> array.
> 
>> I suggest to discuss changing the rules for 'where' generic filter for 
>> protocols:
>> 
>> 1. Don't allow syntax ': P' or '== P' for protocols. Such syntax should be 
>> allowed only for classes, structs & other value types.
>> 
>> 2. For protocol introduce 'is P' syntax, which should mean 'typed exactly as 
>> P, or its derived protocol, or as concrete type conformed to P'. I.e.:
>> 
>> func pick(peppers: PepperType) where 
>> PepperType.Iterator.Element is Pepper
>> 
>> 3. If it is hard to implement (2) today in the "right" way, implement it 
>> with two copies of the same function, one with ":P" and one with "==P"(was 
>> discussed earlier in thread)
> 
> This looks identical to my pitch, only with the operator named “is” instead 
> of “:==“. Unfortunately, we now have Word of God that the Swift team wants to 
> avoid cloning functions à la C++ templates, so it may be a bit of a 
> non-starter.

I’m not the Word of God, nor am I on the core team, I just work here and 
stating my opinions on the matter ;-)

Slava

> 
> Charles
> 
> ___
> 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: Return a subclass for a protocol method without the need for an associatedtype

2016-08-17 Thread Slava Pestov via swift-evolution

> On Aug 17, 2016, at 10:18 AM, Vladimir.S via swift-evolution 
>  wrote:

> But yes, strictly speaking 'make()->Circle?' conforms to protocol requirement 
> 'make()->Shape?', it does returns 'Shape?', so I believe this should be 
> treated as conformance to MyShapeProtocol protocol.

I agree this should be made to work, especially since method overriding 
supports the exact same scenario.

We have two sets of rules, implemented in two different places, for matching 
method overrides and protocol witnesses. We need to unify the rules and the 
code.

Slava

> 
> 
> On 17.08.2016 10:09, Sitton, Yogev via swift-evolution wrote:
>> Hi,
>> 
>> I raised this issue a few months back and discussion has died out since.
>> I’m raising this again to see if there are any objections before I submit a
>> proposal.
>> 
>> 
>> 
>> I have a class that conforms to a protocol which declares a method with a
>> specific return type.
>> In case I want to return a subclass of the return type I am forced to use
>> anassociatedtype.
>> This feels like a hack.
>> 
>> *Example:*
>> 
>> // The protocol
>> protocol MyShapeProtocol {
>> // returns Shape
>> func make() -> Shape?
>> }
>> 
>> // Circle inherits from Shape
>> class Circle : Shape {}
>> 
>> // CircleMaker conforms to the MyShapeProtocol
>> class CircleMaker : MyShapeProtocol {
>> // CircleMaker wants to return Circle which is a type of Shape
>> func make() ->Circle? {
>> return Circle()
>> }
>> }
>> 
>> This will not work.
>> For that to work I’ll need to use toe associatedtype “hack”:
>> 
>> *Example:*
>> protocol MyShapeProtocol {
>> associatedtype ShapeReturnType : Shape
>> func make() -> ShapeReturnType?
>> }
>> 
>> class Circle : Shape {}
>> 
>> class CircleMaker : MyShapeProtocol{
>> func make() ->Circle? {
>> return Circle()
>> }
>> }
>> 
>> What I’m suggesting is to allow to return a subclass for a protocol method
>> without the need for an associatedtype.
>> 
>> Any reason why not?
>> 
>> 
>> ___
>> 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] [Swift4][Pitch] Control struct layout with @layout, @offset, @order

2016-08-17 Thread Slava Pestov via swift-evolution
Hi Russ,

Keep in mind you can control layout of structs by defining them in C (using 
__attribute__((packed)) and so on), and using them as imported types in Swift.

As Mark mentioned, we can add this later if we need it, so it’s probably out of 
scope for now.

Slava

> On Aug 17, 2016, at 11:28 AM, Russ Bishop via swift-evolution 
>  wrote:
> 
> I wanted to gauge the interest in supporting explicit struct layout and 
> alignment.
> 
> The general idea would be to support attributes to create packed structs and 
> set alignment. It will be critical for certain kinds of interop and systems 
> programming in pure Swift. I don’t know about you but I want to write a 
> kernel module in Swift someday :) I’m bringing it up because it probably 
> affects ABI stability and resilience and so meets the requirements for Swift 
> 4 phase 1.
> 
> Hopefully this could be a jumping-off point for further discussion. If the 
> core team doesn’t think this affects ABI stability then we can postpone 
> discussing it until Swift 4 phase 1 wraps up.
> 
> 
> @layout(style: auto, alignment: natural)
> 
> enum LayoutStyle {
> /// Compiler is free to order the fields as it likes
> case automatic
> /// Places a struct's members in source order
> case sequential
> /// Requires each member to have an @order attribute
> case ordered
> /// Requires each member to have an @offset attribute
> case explicit
> }
> 
> Only structs with certain @layout attributes would be exportable to non-Swift 
> languages (assuming such support is added at some point). A struct defined 
> with ordered or explicit layout and as resilient could possibly avoid 
> indirect access to members since the ABI contract guarantees the location of 
> each member.
> 
> 
> enum Alignment {
> /// Compiler decides
> case natural
> /// Align as if the natural alignment were specified bytes
> case bytes(Int)
> }
> 
> 
> 
> @order()
> 
> Specifies the order of the member in memory. Order must start at zero and 
> increase monotonically without gaps. This makes accidental changes to the 
> ordering errors.
> 
> 
> 
> @offset()
> 
> Specifies the offset from the start of the struct where this member should be 
> placed. The size of the struct becomes the highest offset plus the size of 
> the member with that offset.
> 
> It is an open question whether overlapping alignment should be allowed. If it 
> is allowed I’d propose that for any set of members overlapping all of the 
> members must be entirely contained within the largest overlapping member (I’m 
> thinking of C-style unions when the struct format is imposed by something 
> outside your control).
> 
> 
> 
> Thoughts?
> 
> Russ
> 
> 
> 
> 
> 
> ___
> 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] Subclass Existentials

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

> On Feb 1, 2017, at 4:09 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
>> 
>> On Feb 1, 2017, at 3:13 PM, David Hart > > wrote:
>> 
>> Second question inline:
>> 
>> 
>> 
>> Sent from my iPhone
>> On 1 Feb 2017, at 23:09, David Hart > > wrote:
>> 
>>> I did consider it, but didn’t want to put too much on your plate for Swift 
>>> 4. But if you’re mentioning it, I’ll go ahead and add it to the second 
>>> version of the proposal.
>>> 
>>> By the way, what you is your point of view about the discussions we’ve had 
>>> concerning the positioning of the class constraint?
>>> 
>>> David.
>>> 
 On 1 Feb 2017, at 22:58, Douglas Gregor > wrote:
 
 
> On Jan 29, 2017, at 8:39 AM, David Hart  > wrote:
> 
> Hello,
> 
> As promised, I wrote the first draft of a proposal to add class 
> requirements to the existential syntax. Please let me know what you think.
> 
> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md
>  
> 
 This looks good! I’m looking forward to the second draft, but I have one 
 question.
 
 Did you consider the generalized “class” constraint? IIRC, this was in 
 Austin’s larger proposal, and it allowed for (e.g.)
 
typealias CustomStringConvertibleClass = class & 
 CustomStringConvertible// class that conforms to 
 CustomStringConvertible
 
 and potentially a wonderful cleanup where AnyObject ceases to be a weird 
 special protocol and instead becomes
 
typealias AnyObject = Any & class
 
>> 
>> Austin's proposal defines it as:
>> 
>> typealias AnyObject = class
>> 
>> Is Any necessary?
> 
> Nah, it should be okay to just have “class” there.

This would mean ‘class’ can appear anywhere we expect to parse a type, or would 
we have a special grammar rule for the RHS of a typealias?

Slava

> 
>   - Doug
> 
> ___
> 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] [RFC][Proposal] Ease restrictions on protocol nesting

2017-02-06 Thread Slava Pestov via swift-evolution

> On Feb 6, 2017, at 9:12 PM, Karl Wagner  wrote:
> 
> 
>> On 7 Feb 2017, at 06:05, Slava Pestov > > wrote:
>> 
>>> 
>>> On Feb 6, 2017, at 9:00 PM, Karl Wagner via swift-evolution 
>>> > wrote:
>>> - Nested protocols in generic types are not parameterised by the parent's 
>>> generic parameters.
>> So if I write GenericType.SomeProto and GenericType.SomeProto, 
>> is it the same protocol? What about GenericType.SomeProto, is that allowed?
>> 
>> Slava
> 
> GenericType.SomeProto (without parameters) is the only spelling that is 
> allowed. There is no GenericType.SomeProto.
> 
> That way we avoid every bound-generic type creating a new protocol. 
> I think it works really nicely when you consider what it would like like with 
> existential-based capturing. Notice that there is only one 
> ‘MyCollectionView.Source’, and compatibility is determined based on 
> existential constraints.
> 
> - Karl
> 
> 
> class MyCollectionView : UICollectionView {
> 
> protocol Source {
> // [implicit] associatedtype MediaItem

I’m worried this is going to be tricky to implement; we definitely won’t get 
this with the initial implementation of nested protocol types.


> func item(at: Int) -> MediaItem
> var numberOfItems: Int { get }
> }
> var source: Any // 
> Not possible today.

I think for this use-case, it makes sense to allow the protocol itself to be 
parametrized.

Slava

> }
> 
> class BookSource: MyCollectionView.Source {
> typealias MediaItem = Book
> 
> func item(at: Int) -> Book { /* ... */ }
> var numberOfItems: Int { /* ... */ }
> }
> 
> class DummySource: MyCollectionView.Source where MediaItem: 
> DummyConstructable {
> // associatedtype 'MediaItem' bound to generic parameter.
> 
> func item(at: Int) -> MediaItem { /* ... */ }
> var numberOfItems: Int  { /* ... */ } 
> }
> 
> MyCollectionView().source = BookSource()
> MyCollectionView().source = DummySource()
> MyCollectionView().source  = DummySource() // type is: DummySource
> MyCollectionView().source = DummySource() // type is: 
> DummySource
> 
> 
> 

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


Re: [swift-evolution] [RFC][Proposal] Ease restrictions on protocol nesting

2017-02-06 Thread Slava Pestov via swift-evolution

> On Feb 6, 2017, at 9:00 PM, Karl Wagner via swift-evolution 
>  wrote:
> - Nested protocols in generic types are not parameterised by the parent's 
> generic parameters.
So if I write GenericType.SomeProto and GenericType.SomeProto, is 
it the same protocol? What about GenericType.SomeProto, is that allowed?

Slava

> - Some observations as to how capturing might be implemented in the future, 
> standard library benefits.
> 
> This is a chance for everybody to go over it once more before the actual 
> review.
> 
> Github: https://github.com/apple/swift-evolution/pull/552 
> 
> Raw:
> 
> # Ease restrictions on protocol nesting
> 
> * Proposal: [SE-](-ease-protocol-nesting.md)
> * Authors: [Karl Wagner](https://github.com/karlwa 
> )
> * Review Manager: TBD
> * Status: **Awaiting review**
> 
> *During the review process, add the following fields as needed:*
> 
> * Decision Notes: 
> [Rationale](https://lists.swift.org/pipermail/swift-evolution/ 
> ), [Additional 
> Commentary](https://lists.swift.org/pipermail/swift-evolution/ 
> )
> * Bugs: [SR-](https://bugs.swift.org/browse/SR- 
> ), 
> [SR-](https://bugs.swift.org/browse/SR- 
> )
> * Previous Revision: 
> [1](https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/-filename.md
>  
> )
> * Previous Proposal: [SE-](-filename.md)
> 
> ## Introduction
> 
> Protocols define a way to express a syntactic and semantic contract. This 
> semantic nature means that protocols are often intended to used in the 
> context of one specific type (such as a 'delegate' protocol). Similarly, 
> protocols sometimes wish to define specific types to be used within the 
> context of that protocol (usually an `enum`).
> 
> This proposal would allow protocols to be nested in other types (including 
> other protocols), and for structural types to be nested inside of protocols 
> -- subject to a few constraints.
> 
> Swift-evolution thread: [Discussion thread topic for that 
> proposal](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20161017/028112.html
>  
> )
> 
> ## Motivation
> 
> Nesting types inside other types allows us to scope their usage and provide a 
> cleaner interface. Protocols are an important part of Swift, and many popular 
> patterns (for example, the delegate pattern) define protocols which are 
> intended to be used in the semantic context of other types. It would be nice 
> to apply type-nesting here: `MyClass.Delegate` reads better than 
> `MyClassDelegate`, and literally brings structure to large frameworks.
> 
> Similarly, we have examples of protocols in the standard library which define 
> supporting types to be used in the context of that protocol - 
> `FloatingPointClassification`, `FloatingPointSign`, and 
> `FloatingPointRoundingRule` are enums which are used by various members of 
> the `FloatingPoint` protocol. These types are part of the contract which the 
> protocol defines, and so it would be nice if they could be nested within the 
> protocol to reflect that (i.e. `FloatingPoint.Classification`, 
> `FloatingPoint.Sign`, `FloatingPoint.RoundingRule`).
> 
> ## Proposed solution
> 
> The first part is to allow protocols to be nested inside of structural types 
> (for example, in the delegate pattern):
> 
> ```swift
> class AView {// A regular-old class
> protocol Delegate: class {   // A nested protocol
> func somethingHappened()
> }
> weak var delegate: Delegate?
> }
> 
> class MyDelegate: AView.Delegate {
> func somethingHappened() { /* ... */ }
> }
> ```
> 
> The second part is to allow nominal types to be nested inside of protocols 
> (for example, `FloatingPoint.Sign`).
> 
> ```swift
> protocol FloatingPoint {  
> // 'Sign' is required for conformance, therefore good candidate for 
> nesting.
> enum Sign {
> case plus
> case minus
> }
> var sign: Sign { get }
> }
> ```
> 
> Similarly, protocols may be nested inside other protocols:
> 
> ```swift
> protocol Scrollable: class { // A regular-old protocol.
> var currentPosition: Position { get }
> 
> protocol Delegate: class {   // A nested protocol.
> func scrollableDidScroll(_: Scrollable, from: Position)
> }
> weak var delegate: Delegate?
> }
> 
> class MyScrollable: Scrollable {
> var currentPosition = Position.zero
> 
> weak var delegate: Delegate?
> }
> 
> extension MyController: Scrollable.Delegate {
> func scrollableDidScroll(_ 

Re: [swift-evolution] [apple/swift-evolution] Ease restrictions on protocol nesting (#552)

2017-02-06 Thread Slava Pestov via swift-evolution

> On Feb 5, 2017, at 10:06 AM, Karl  wrote:
> 
> @slavapestov  I can't reply to your comments 
> directly so will have do batch them here:
> 
> With the current implementation of name lookup, qualified and unqualified 
> lookup will find the nominal type as a member of the conforming type. In 
> Swift 3 there was a bug where unqualified name lookup didn't find a 
> typealias, but this is fixed now.
> 
> I think the nicest rule would be that, if the nested type is used by a 
> protocol requirement, it does actually get imported in to the namespace of 
> the conforming type (the compiler would generate a hidden typealias). That 
> way, you would actually get something called Float.Sign and Double.Sign, 
> could refer to them as just Sign from extensions, etc.
> 
> For everything else (i.e. nested types which are not used by requirements and 
> do not capture associated types), they likely have nothing to do with the 
> conforming type. It makes sense then, that everybody should have to spell it 
> as RandomAccessCollection.Concurrent and not just .Concurrent, 
> regardless of whether or not the current context conforms to 
> RandomAccessCollection.
> 
> 

This sounds too complex — the unqualified lookup implementation is tricky 
enough as-is, so let’s stick with the simplest rule that makes sense: 
unqualified lookup inside a concrete type will find all members (requirements, 
as well as nested types) of any protocol that the concrete type conforms to.

Slava
> We leave the door open for capturing types (when they are possible) to be 
> spelled differently, so you could maybe just write let myVar: Concurrent 
> inside an extension of Array in order to get a 
> RandomAccessCollection.Concurrent where Collection == Array.
> 
> At the very least, it is a separate proposal :)
> 
> I'm worried that if we leave it, there may be ABI decisions we take now which 
> make it unpalatable later. Even if this part of the proposal can't be 
> implemented right away, it'd be nice to keep it; especially since you can 
> have generic NSObject subclasses, and it's reasonable to want to have nested 
> delegate protocols inside of them.
> 
> 

Once we figure out the right semantics for protocols inside generic types, we 
should be able to implement them without disturbing ABI. Again, speaking as 
someone who is likely to end up implementing this proposal were it to be 
accepted, it makes sense to tackle the non-generic protocol case first, even if 
the proposal has generic protocols.

Also, if we allow this:

struct G {
  protocol P {
func foo() -> T
  }
}

Why not go all the way and allow this?

protocol P {
  func foo() -> T
}

They’re essentially equivalent.

But yeah, that’s definitely a separate proposal.

Slava

> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub 
> , 
> or mute the thread 
> .
> 

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


Re: [swift-evolution] define backslash '\' as a operator-head in the swift grammar

2017-02-06 Thread Slava Pestov via swift-evolution
I really have nothing to add to this discussion, except for this fun fact: 
apparently, the backslash was added to ASCII so you could write /\ and \/ 
operators: http://www.bobbemer.com/BACSLASH.HTM 


Slava

> On Feb 5, 2017, at 7:29 AM, Nicolas Fezans via swift-evolution 
>  wrote:
> 
> Dear all,
> 
> This is a rather simple proposal to add '\' (backslash character) as a valid 
> operator-head in the swift grammar.
> 
> One argument for it, is that there exist a backslash operator in the 
> MATLAB/Scilab/Octave languages. In this languages A\B solves the linear 
> system A*X = B for X (or the least square problem associated to it if the 
> system of equations is overdetermined). I am doing some numerical computation 
> in Swift and it would be nice to be able to declare the same operator name 
> for this functionality.
> 
> I might have missed some arguments for not adding them, but I seems to me 
> that until now the \ character is only used inside of string literals. If 
> that is the case, both uses should never generate a conflict or be ambiguous, 
> isn't it? (String literals keep their interpretation of \ and \ used 
> otherwise within the swift code will be interpreted as an operator or as the 
> beginning of an operator)
> 
> I am curious to see what will be the feedback on this.
> 
> Nicolas
> ___
> 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] I think we need more to our type calculus

2017-02-08 Thread Slava Pestov via swift-evolution

> On Feb 8, 2017, at 12:09 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> I’ve been trying to get the maximum of a list of counts. I started by using 
> “myCollection.map { $0.myCountProperty }.reduce(0, max)”. Then I thought I 
> should really use the value closest to negative infinity as the base. The 
> problem is how to get that value. The current hard-coded “0” works because 
> the count type ultimately aliases “Int”, but shouldn’t have to count on that. 
> I put in “MyCountType.min”, where “MyCountType” is hard coded from the docs 
> of “myCountProperty”, but I shouldn’t have to do that either.
> 
> There is a “type(of:)” global function, which I did use. But not only did I 
> have to make up an expression to go in there, its return value, some sort of 
> meta-type stuff I don’t understand, can’t be used on the right side of a 
> “typealias” construct. I ultimately used “let lowestCount = type(of: 
> anElement.myCountProperty).min” to get what I needed.
> 
> Some queries/requests:
> 
> 1. Is the expression within “type(of:)” evaluated?

Yes. Eg,

class Base {}
class Derived : Base {}

func foo() -> Base { return Derived() }

type(of: foo()) // this is Derived.self, not Base.self

> 2. I think we need the equivalent of "std::declval” from C++. Especially if 
> the answer to (1) is yes.
> 3. Why isn’t the return type(?) of “type(of:)” compile-time enough to be used 
> as a type-alias?

type(of:) is not a real function because it’s return type depends on the input 
type in a funny way. If the input type T is an existential, then type(of:) 
returns an existential metatype; otherwise, it returns a concrete metatype. So 
it’s almost as if the signature is (T) -> (T.Type), but not quite.

Slava

> 4. Should we add something like the C++ type-traits collection of generic 
> structures to give use type information as type-aliases or type-level 
> instances?
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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] Warning when omitting default case for imported enums

2017-02-07 Thread Slava Pestov via swift-evolution

> On Feb 7, 2017, at 6:16 PM, Dany St-Amant via swift-evolution 
>  wrote:
> 
> 
> Le 7 févr. 2017 à 14:45, Robert Widmann via swift-evolution 
> > a écrit :
> 
>> I lean +1, but this answer on its own seems incomplete.  Exhaustiveness is 
>> an important property, and it’s not clear what happens here now when you 
>> fall through a “complete” case tree without matching a pattern, and in that 
>> sense this plan solves a problem.  But it also would hinder a “future-you” 
>> from going back and dealing with the ramifications of swapping a dependency 
>> for a newer version, in that with a default now covering the rest of the 
>> cases the compiler is unable to tell you which cases you are actually 
>> missing post-upgrade.
>> 
> 
> I have not read the ABI stability stuff, so not sure if adding a new case to 
> an enum inside a library can be made backward compatible but that would be 
> nice.

The plan of record currently is to have a ‘closed’ attribute for enums which 
allows the default case to be omitted for an exhaustive switch. Closed enums 
cannot have new cases added after the fact. Enums that are not marked ‘closed’ 
will require a default case when used outside of their defining module, and 
adding new cases will be permitted without breaking ABI.

(If anyone wants to take a look, this is sort of implemented today, except you 
have to enable the resilient ABI explicitly with the -enable-resilience 
frontend flag, and @closed is spelled ‘@_fixed_layout’. Also 100% unsupported 
and undocumented).

> Handling this unexpected new value in the currently compiled user code should 
> be as important as telling the owner of the user code that he must handle a 
> new case.
> 
> Would a new pseudo-default keyword (unexpected, undefined) help here? Such 
> keyword would require the switch statement to be exhaustive so it doesn't act 
> like 'default' for switch exhaustiveness status at compile time,  but does 
> act like 'default' at runtime.
> 
> switch data {
>   case .one: { print("one') }
>   case .two: { print("two") }
>   undefined: { print("unexpected value") }
> }
> 
> Replacing the library with one providing .three, will cause this previously 
> compile code to print "unexpected value", and would cause the code to fail to 
> compile against this same new library.
> 
> Dany
> 
> 
>> Library Evolution 
>>  
>> includes what I think is the more complete response here: An @closed 
>> attribute for enums where a switch is guaranteed to be exhaustive.  (Though, 
>> after the open discussion, I wonder if that keyword can’t be reused in some 
>> way to provide the inverse restriction instead).
>> 
>>> On Feb 7, 2017, at 10:12 AM, Tanner Nelson via swift-evolution 
>>> > wrote:
>>> 
>>> Hello Swift Evolution,
>>> 
>>> I'd like to propose that a warning be emitted when default cases are 
>>> omitted for enums from other modules. 
>>> 
>>> What this would look like:
>>> 
>>> OtherModule:
>>> ```
>>> public enum SomeEnum {
>>> case one
>>> case two
>>> }
>>> 
>>> public let global: SomeEnum = .one
>>> ```
>>> 
>>> executable:
>>> ```
>>> import OtherModule
>>> 
>>> switch OtherModule.global {
>>> case .one: break
>>> case .two: break
>>> ^ ⚠︎ Warning: Default case recommended for imported enums. Fix-it: 
>>> Add `default: break`
>>> }
>>> ```
>>> 
>>> Why:
>>> 
>>> Allowing the omission of a default case in an exhaustive switch makes the 
>>> addition of a new case to the enum a breaking change. 
>>> In other words, if you're exhaustively switching on an enum from an 
>>> imported library, the imported library can break your code by adding a new 
>>> case to that enum (which the library authors may erroneously view as an 
>>> additive/minor-bump change).
>>> 
>>> Background:
>>> 
>>> As a maintainer of a Swift framework, public enums have been a pain point 
>>> in maintaining semver. They've made it difficult to implement additive 
>>> features and have necessitated the avoidance of enums in our future public 
>>> API plans.
>>> 
>>> Related Twitter thread: 
>>> https://twitter.com/tanner0101/status/796860273760104454 
>>> 
>>> 
>>> Looking forward to hearing your thoughts.
>>> 
>>> Best,
>>> Tanner
>>> 
>>> Tanner Nelson
>>> Vapor 
>>> +1 (435) 773-2831
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> 

Re: [swift-evolution] Compile-time generic specialization

2017-02-07 Thread Slava Pestov via swift-evolution

> On Feb 5, 2017, at 8:28 AM, Abe Schneider via swift-evolution 
>  wrote:

> The suggested method to get around this issue is to use a protocol to create 
> a witness table, allowing for runtime dispatch. However, this approach is not 
> ideal in all cases because: (a) the overhead of runtime dispatch may not be 
> desirable, especially because this is something that can be determined at 
> compile time; and

Just as the compiler is able to generate specializations of generic functions, 
it can also devirtualize protocol method calls. The two optimizations go 
hand-in-hand.

> One potential solution would be to add/extend an attribute for generic 
> functions that would force multiple versions of that function to be created. 
> There is already there is a `@_specialize` attribute, but you have to: (a) 
> manually write out all the cases you want to cover; and (b) only affects the 
> compiled code, which does not change this behavior. Due to the fact that 
> `@_specialize` exists, I’m going to assume it wouldn’t be a major change to 
> the language to extend the behavior to compile-time dispatch.

In Swift, specialization and devirtualization are optimization passes which are 
performed in the SIL intermediate representation, long after type checking, 
name lookup and overload resolution. In this sense it is completely different 
from C++, where parsed templates are stored as a sort of untyped AST, allowing 
some delayed name lookup to be performed.

Implementing C++-style templates would be a major complication in Swift and not 
something we’re likely to attempt at any point in time. The combination of 
specialization and devirtualization should give you similar performance 
characteristics, with the improved type safety gained from being able to 
type-check the unspecialized generic function itself.

> 
> 
> Thanks!
> Abe
> ___
> 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] Recursive protocol constraints

2017-02-07 Thread Slava Pestov via swift-evolution

> On Feb 7, 2017, at 9:12 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> I would like to get the PR revised and into the review process soon, as it 
> should have been a month ago. Is there a good place to review the in-progress 
> work? I think it would go a long way to help complete the auditing of the 
> necessary standard library changes.

I don’t think the code is at a stage yet where you can actually define and use 
a recursive conformance. Doug is still squashing recursive walks over nested 
types, which are by definition non-terminating with a recursive conformance.

Slava

> 
> (Alternately, if anyone is interested in picking it up from me I'm open to 
> that as well. Whatever is best for the community is the best way forward.)
> 
> Austin
> 
>> On Feb 7, 2017, at 8:57 PM, Douglas Gregor  wrote:
>> 
>> 
>> 
>> Sent from my iPhone
>> 
>>> On Feb 7, 2017, at 3:05 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
 on Tue Feb 07 2017, Rex Fenley  wrote:
 
 Does "Permit where clauses to constrain associated types" (
 https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md)
 also
 include "Recursive protocol constraints"? The "Motivation" section seems to
 imply this. If not, will this be making it into Swift 4?
>>> 
>>> They're related but distinct issues.  We're working on delivering both
>>> of them for Swift 4.
>> 
>> Austin Zheng was working on a proposal for recursive protocols conformances, 
>> but we're charging forward on the implementation regardless. It's a 
>> delightful feature. 
>> 
>> - Doug
>> 
>>> 
>>> -- 
>>> -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] Public struct init is unexpectedly internal

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

> On Jan 30, 2017, at 1:30 AM, David Sweeris  wrote:
> 
> 
>> On Jan 30, 2017, at 1:21 AM, Slava Pestov > > wrote:
>> 
>>> 
>>> On Jan 30, 2017, at 1:12 AM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> So I’ve got this code in a package called “SomeLib":
>>> public struct SomeType {
>>> public var text = "SomeText"
>>> }
>>> and then, in another package, write this:
>>> import SomeLib
>>> print(SomeType().text)
>>> and then run swift build, I get this error:
>>> error: 'SomeType' initializer is inaccessible due to 'internal' protection 
>>> level
>>> 
>>> "Well that’s odd… there isn’t even an initializer to be internal or 
>>> public”, I said to myself. Then I proceeded to futz around with it for a 
>>> while before having a lightbulb moment:
>>> public struct SomeType {
>>> public var text = "SomeText"
>>> public init() {} //this fixes it
>>> }
>>> 
>>> 
>>> In cases like this where the struct is public and all its stored properties 
>>> are both public and already have values, should we make the implicit init() 
>>> function also be public? Seems like the “least surprising” thing to do.
>> 
>> This is intentional. I believe the core team’s rationale is that public APIs 
>> should always be explicitly written down in source. So your example above 
>> defining a public init() is correct.
> 
> Oh, I knew (well, suspected) it was intentional… I just didn't recall if we’d 
> discussed this specific scenario before. If we did, then I don’t want to 
> rehash it.

I think there was a proposal floating around for ‘flexible member-wise 
initialization’. This would allow explicitly defining an initializer (to make 
it public or @_inlineable or whatever) without writing out the boilerplate to 
initialize all members.

I don’t have the link offhand, and I don’t remember what the conclusion was, 
but if you’re interested you might want to look into it and revive it. ;-)

Slava

> 
> - Dave Sweeris

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


Re: [swift-evolution] Public struct init is unexpectedly internal

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

> On Jan 30, 2017, at 1:12 AM, David Sweeris via swift-evolution 
>  wrote:
> 
> So I’ve got this code in a package called “SomeLib":
> public struct SomeType {
> public var text = "SomeText"
> }
> and then, in another package, write this:
> import SomeLib
> print(SomeType().text)
> and then run swift build, I get this error:
> error: 'SomeType' initializer is inaccessible due to 'internal' protection 
> level
> 
> "Well that’s odd… there isn’t even an initializer to be internal or public”, 
> I said to myself. Then I proceeded to futz around with it for a while before 
> having a lightbulb moment:
> public struct SomeType {
> public var text = "SomeText"
> public init() {} //this fixes it
> }
> 
> 
> In cases like this where the struct is public and all its stored properties 
> are both public and already have values, should we make the implicit init() 
> function also be public? Seems like the “least surprising” thing to do.

This is intentional. I believe the core team’s rationale is that public APIs 
should always be explicitly written down in source. So your example above 
defining a public init() is correct.

Slava

> 
> - Dave Sweeris
> ___
> 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] Warn about unused Optional.some(())

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

> On Jan 30, 2017, at 2:58 PM, Daniel Duan via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> Right now, expressions that evaluates to Optional<()>, 
> Optional>… gets special treatment when it’s unused. For example:
> 
> func f(s: String) {}
> let s: String = “”
> s.map(f) // no warning here, even tho the resulting type is `Optional<()>` 
> and unused.
> 
> func g() throws {}
> try? g() // no warnings here neither.
> 
> This is convenient, but encourages composing map/filter/reduce, etc with 
> side-effect-ful functions, which we have found a few cases of in our 
> production code recently. Granted, these cases could’ve been caught with more 
> careful code reviews. But we wouldn’t have missed them if this “feature” 
> didn’t exist.
> 
> I think we should remove the special treatment so that code in the example 
> above would generate a warning about `()?` being unused. Users can silence it 
> manually by assigning the result to `_`. 
> 
> OTOH, this would undermine the convenience of `try?` when the throwing 
> function don’t return anything.

IMHO, using ‘try?’ to ignore an error result, instead of just turning it into 
an optional, is an anti-pattern, and forcing users to write ‘_ = try? foo()’ 
might not be so bad…

> 
> What do y’all think?
> 
> Daniel Duan
> ___
> 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] Checking in; more thoughts on arrays and variadic generics

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

> On Jan 27, 2017, at 11:44 AM, Karl Wagner via swift-evolution 
>  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?

> 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.

> 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.

> 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] 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 
>>> > 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] Subclass Existentials

2017-01-29 Thread Slava Pestov via swift-evolution
This is a nice generalization of the existing protocol composition syntax. 
Implementation might get a little tricky — this touches a lot of things, such 
as inheritance clauses, constraints in generic signatures, and casts. It would 
require thorough testing.

There are also a few odd corner cases to sort out:

typealias T = SomeClass & SomeProtocol

class C : T { // should we allow this? probably yes
}

protocol P : T { // should we allow this? probably no
}

Slava

> On Jan 29, 2017, at 8:39 AM, David Hart via swift-evolution 
>  wrote:
> 
> Hello,
> 
> As promised, I wrote the first draft of a proposal to add class requirements 
> to the existential syntax. Please let me know what you think.
> 
> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md
>  
> 
> 
> Regards,
> David.
> 
> Existentials for classes conforming to protocols
> 
> Proposal: SE- 
> 
> Authors: David Hart , Austin Zheng 
> 
> Review Manager: TBD
> Status: TBD
>  
> Introduction
> 
> This proposal brings more expressive power to the type system by allowing 
> Swift to represent existentials of classes and subclasses which conform to 
> protocols.
> 
>  
> Motivation
> 
> Currently, the only existentials which can be represented in Swift are 
> conformances to a set of protocols, using the :
> 
> let existential: Hashable & CustomStringConvertible
> On the other hand, Objective-C is capable of expressing existentials of 
> subclasses conforming to protocols with the following syntax:
> 
> UIViewController* existential;
> We propose to provide similar expressive power to Swift, which will also 
> improve the bridging of those types from Objective-C.
> 
>  
> Proposed
>  solution
> 
> The proposal keeps the existing & syntax but allows the first element, and 
> only the first, to be of class type. The equivalent declaration to the above 
> Objective-C declaration would look like this:
> 
> let existential: UIViewController & UITableViewDataSource & 
> UITableViewDelegate
> As in Objective-C, this existential represents classes which have 
> UIViewController in their parent inheritance hierarchy and which also conform 
> to the UITableViewDataSource and UITableViewDelegate protocols.
> 
> As only the first element in the existential composition syntax can be a 
> class type, and by extending this rule to typealias expansions, we can make 
> sure that we only need to read the first element to know if it contains a 
> class requirement. As a consequence, here is a list of valid and invalid code 
> and the reasons for them:
> 
> let a: Hashable & CustomStringConvertible
> // VALID: This is still valid, as before
> 
> let b: MyObject & Hashable
> // VALID: This is the new rule which allows an object type in first position
> 
> let c: CustomStringConvertible & MyObject
> // INVALID: MyObject is not allowed in second position. A fix-it should help 
> transform it to:
> // let c: MyObject & CustomStringConvertible
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let d: Hashable & MyObjectStringConvertible
> // INVALID: The typealias expansion means that the type of d expands to 
> Hashable & MyObject & CustomStringConvertible, which has the class in the 
> wrong position. A fix-it should help transform it to:
> // let d: MyObjectStringConvertible & Hashable
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let e: MyOtherObject & MyObjectStringConvertible
> // INVALID: The typealias expansion would allow an existential with two class 
> requirements, which is invalid
> The following examples could technically be legal, but we believe we should 
> keep them invalid to keep the rules simple:
> 
> let a: MyObject & MyObject & CustomStringConvertible
> // This is equivalent to MyObject & CustomStringConvertible
> 
> let b: MyObjectSubclass & MyObject & Hashable
> // This is equivalent to MyObjectSubclass & Hashable
> 
> typealias MyObjectStringConvertible = MyObject & CustomStringConvertible
> let d: MyObject & MyObjectStringConvertible
> // This is equivalent to MyObject & CustomStringConvertible
>  
> Source
>  compatibility
> 
> This is a source breaking change. All types bridged from Objective-C 

Re: [swift-evolution] extending typealiases

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

> On Jan 29, 2017, at 1:03 PM, Matt Whiteside via swift-evolution 
>  wrote:
> 
> In Swift 3.1, I was happy to see that we can now extend types with concrete 
> constraints.  I think one other feature which fits nicely with this new 
> capability would be extending typealiases, like this:
> 
> typealias Vector = Array
> 
> extension Vector { 
>...
> }
> 
> Which currently doesn't compile due to:  "Constrained extension must be 
> declared on the unspecialized generic type 'Array' with constraints specified 
> by a 'where’ clause”
> 
> What is other people’s interest level?  How possible would it be to add this?

I think this particular case would be pretty easy to add, but there is a more 
general case with generic typealiases that requires some thought:

typealias OptionalArray = Optional

extension OptionalArray {
  …
}

Without generic typealiases, you might imagine this could be written as 
something like

extension  Optional {
  …
}

I think this is called out in the generics manifesto as a potential future 
feature. I’m not sure how much work it would take to add it but I imagine it’s 
not entirely trivial.

Slava

> 
> -Matt
> 
> 
> 
> ___
> 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] Subclass Existentials

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

> On Jan 29, 2017, at 2:05 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On Jan 29, 2017, at 3:52 PM, Xiaodi Wu > > wrote:
>> 
>> On Sun, Jan 29, 2017 at 3:35 PM, Matthew Johnson > > wrote:
>> 
>>> On Jan 29, 2017, at 3:24 PM, Xiaodi Wu >> > wrote:
>>> 
>>> On Sun, Jan 29, 2017 at 3:11 PM, Matthew Johnson >> > wrote:
>>> 
 On Jan 29, 2017, at 3:05 PM, Xiaodi Wu > wrote:
 
 On Sun, Jan 29, 2017 at 2:40 PM, Matthew Johnson > wrote:
 
> On Jan 29, 2017, at 2:25 PM, Xiaodi Wu  > wrote:
> 
> On Sun, Jan 29, 2017 at 2:16 PM, Matthew Johnson  > wrote:
> 
>> On Jan 29, 2017, at 2:01 PM, Xiaodi Wu > > wrote:
>> 
>> On Sun, Jan 29, 2017 at 1:37 PM, Matthew Johnson > > wrote:
>> 
>> 
>> Sent from my iPad
>> 
>> On Jan 29, 2017, at 12:58 PM, Xiaodi Wu via swift-evolution 
>> > wrote:
>> 
>>> Cool. Another avenue of improvement here is relaxing the single-class 
>>> spelling rule for the sake of composing typealiases.
>>> 
>>> As Matthew mentioned, if I have class Base and typealiases Foo = Base & 
>>> Protocol1 and Bar = Base & Protocol2, it'd be nice to allow Foo & Bar.
>>> 
>>> It'd be nice to go one step further: given class Derived : Base, if I 
>>> have typealiases Foo2 = Base & Protocol1 and Bar2 = Derived & 
>>> Protocol2, then it could be permitted to write Foo2 & Bar2, since there 
>>> is effectively only one subclass requirement (Derived).
>>> 
>>> As I understand it, the rationale for allowing only one subclass 
>>> requirement is that Swift supports only single inheritance. Thus, two 
>>> disparate subclass requirements Base1 & Base2 would make your 
>>> existential type essentially equivalent to Never. But Base1 & Base1 & 
>>> Base1 is fine for the type system, the implementation burden (though 
>>> greater) shouldn't be too awful, and you would measurably improve 
>>> composition of typealiases.
>> 
>> Yes, this is what I was indicating in my post as well.
>> 
>> Are you suggesting that Base1 & Base2 compose to a type that is treated 
>> identically to Never do you think it should be an immediate compiler 
>> error?  I remember having some discussion about this last year and think 
>> somebody came up with a very interesting example of where the former 
>> might be useful.
>> 
>> Last year's discussion totally eludes me for some reason. But sure, if 
>> deferring the error until runtime is actually useful then why not? In 
>> the absence of an interesting use case, though, I think it'd be nice for 
>> the compiler to warn you that Base1 & Base2 is not going to be what you 
>> want.
> 
> Deferring to runtime isn’t what I mean.  If you try to actually *do* 
> anything that requires an instance of `Base1 & Based` (which you almost 
> always would) you would still get a compile time error.
> 
> I managed to dig up the example from last year’s thread and it is 
> definitely a good one:
> 
> func intersection(ts; Set, us: Set) -> Set
> 
> The desire is that we are always able to produce a result set.  When T & 
> U is uninhabitable it will simply be an empty set just like Set 
> has a single value which is the empty set.
> 
> Currently, Set is impossible because Never is not Hashable :)
 
 Ahh, good point.  I hadn’t tried it.  It can easily be made Hashable with 
 a simple extension though - this code compiles today:
 
 extension Never: Hashable {
 public var hashValue: Int { return 0 }
 }
 public func ==(lhs: Never, rhs: Never) -> Bool { return false }
 let s = Set()
 
> Since concrete types *can't* be used, this example seems like it'd be of 
> little use currently. How widely useful would it be to have an 
> intersection facility such as this when T != U even if that restriction 
> were lifted, though? Seems like the only real useful thing you can do 
> with generic Set is based on the fact that it'd be Set. 
> Other than those immediate thoughts, I'll have to think harder on this.
 
 Sure, it’s possible that this is the only interesting example and may not 
 have enough value to be worthwhile.  But I found it 

Re: [swift-evolution] [Discussion] Allowing extending existentials

2017-02-21 Thread Slava Pestov via swift-evolution

> On Feb 21, 2017, at 11:34 PM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> I’d love if we could extend the idea even further. It would be great to be 
> able to extend the typealias type, because it can be a more constrained type 
> (with a where clause).
> 
> protocol P {
> associatedtype Q
> }
> class C {}
> 
> typealias CP = C & P where Q == Int
> 
> extension CP { … }
> This would make a lot of constrained extension vanish.
> 
> 

Once we have generalized existentials, it should be possible to make something 
like the above desugar into a constrained extension.

Slava
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 22. Februar 2017 um 08:26:33, David Hart via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> Yes, but it's not very discoverable. Plus, if the subclass existentials 
>> proposal is accepted, it would actually allow us to do:
>> 
>> class C {}
>> extension C & P1 {}
>> 
>> On 22 Feb 2017, at 08:06, Jacob Bandes-Storch > > wrote:
>> 
>>> This works today:
>>> 
>>> protocol P1{}
>>> protocol P2{}
>>> 
>>> extension P1 where Self: P2 {
>>> func foo() {}
>>> }
>>> 
>>> func bar(x: P1 & P2) {
>>> x.foo()
>>> }
>>> 
>>> 
>>> On Tue, Feb 21, 2017 at 10:53 PM, David Hart via swift-evolution 
>>> > wrote:
>>> Hello list,
>>> 
>>> Found out yesterday that you can’t extend all existentials in Swift:
>>> 
>>> protocol P1 {}
>>> extension P1 {}
>>> // works as expected
>>> 
>>> protocol P2 {}
>>> extension P1 & P2 {}
>>> // error: non-nominal type 'P1 & P2' cannot be extended
>>> 
>>> extension Any {}
>>> // error: non-nominal type 'Any' cannot be extended
>>> 
>>> extension AnyObject {}
>>> // error: 'AnyObject' protocol cannot be extended
>>> 
>>> I’d like to write a proposal to lift some of those restrictions. But the 
>>> question is: which should be lifted? P1 & P2 seems like an obvious case. 
>>> But what about Any and AnyObject? Is there a design reason that we 
>>> shouldn’t allow it?
>>> 
>>> David.
>>> 
>>> ___
>>> 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 
> 

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


Re: [swift-evolution] [Discussion] Allowing extending existentials

2017-02-21 Thread Slava Pestov via swift-evolution

> On Feb 21, 2017, at 10:53 PM, David Hart via swift-evolution 
>  wrote:
> 
> Hello list,
> 
> Found out yesterday that you can’t extend all existentials in Swift:
> 
> protocol P1 {}
> extension P1 {}
> // works as expected
> 
> protocol P2 {}
> extension P1 & P2 {}
> // error: non-nominal type 'P1 & P2' cannot be extended

This will make name lookup rather complicated. I’d rather not do it. As Jacob 
mentions, you can almost simulate it with a constrained extension.

> 
> extension Any {}
> // error: non-nominal type 'Any' cannot be extended
> 
> extension AnyObject {}
> // error: 'AnyObject' protocol cannot be extended

These two are by design. In the future, AnyObject will be ‘special’ (basically 
we want to model it as ‘Any & class’), and not a protocol.

Slava

> 
> I’d like to write a proposal to lift some of those restrictions. But the 
> question is: which should be lifted? P1 & P2 seems like an obvious case. But 
> what about Any and AnyObject? Is there a design reason that we shouldn’t 
> allow it?
> 
> David.
> ___
> 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: Compound name `foo(:)` for nullary functions

2017-02-21 Thread Slava Pestov via swift-evolution

> On Feb 21, 2017, at 11:05 PM, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> Evolutioniers,
> 
> Compound name syntax — foo(_:), foo(bar:), foo(bar:baz:) — is used to 
> disambiguate references to functions. (You might've used it inside a 
> #selector expression.) But there's currently no compound name for a function 
> with no arguments.
> 
> func foo() {}  // no compound syntax for this one :(
> func foo(_ bar: Int) {}  // foo(_:)
> func foo(bar: Int) {}  // foo(bar:)
> func foo(bar: String, baz: Double) {}  // foo(bar:baz:)
> 
> Given these four functions, only the first one has no compound name syntax. 
> And the simple reference "let myfn = foo" is ambiguous because it could refer 
> to any of the four. A workaround is to specify a contextual type, e.g. "let 
> myfn = foo as () -> Void".
> 
> I filed SR-3550  for this a while ago, 
> and there was some discussion in JIRA about it. I'd like to continue 
> exploring solutions here and then write up a formal proposal.
> 
> To kick off the discussion, I'd like to propose foo(:) for nullary functions.

I like this idea.

> 
> Advantages:
> - the colon marks a clear similarity to the foo(bar:) form when argument 
> labels are present.
> - cutely parallels the empty dictionary literal, [:].
> 
> Disadvantages:
> - violates intuition about one-colon-per-argument.
> - the parallel between #selector(foo(:)) and @selector(foo) is not quite as 
> obvious as between #selector(foo(_:)) and @selector(foo:).
> 
> 
> For the sake of discussion, another option would be foo(_). This was my 
> original choice, and I like that the number of colons matches the number of 
> parameters. However, it's a little less obvious as a function reference. It 
> would preclude _ from acting as an actual identifier, and might conflict with 
> pattern-matching syntax (although it appears functions can't be compared with 
> ~= anyway).

foo(_) looks like a pattern to me. Even if it doesn’t introduce ambiguity in 
the grammar it might be confusing.

> 
> 
> Looking forward to everyone's bikeshed color ideas,
> Jacob
> ___
> 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] [Discussion] Allowing extending existentials

2017-02-21 Thread Slava Pestov via swift-evolution

> On Feb 21, 2017, at 11:42 PM, David Hart via swift-evolution 
>  wrote:
> 
> If we drop the idea of extending Any and AnyObject (which is out of scope), 
> does the fact that what is left is syntactic sugar make it unsuitable for 
> Swift 4? I remember Chris saying syntactic sugar is not the goal for Swift 4, 
> but this syntactic sugar looks really sweet (pun intended).
> 

It’s unlikely we’ll make it a priority to implement anything like that in the 
Swift 4 timeframe, but PRs are more than welcome ;-)

Slava

> On 22 Feb 2017, at 08:36, Douglas Gregor  > wrote:
> 
>> 
>> 
>> Sent from my iPhone
>> 
>> On Feb 21, 2017, at 11:25 PM, David Hart via swift-evolution 
>> > wrote:
>> 
>>> Yes, but it's not very discoverable. Plus, if the subclass existentials 
>>> proposal is accepted, it would actually allow us to do:
>>> 
>>> class C {}
>>> extension C & P1 {}
>> 
>> ... which is 
>> 
>> extension P1 where Self: C1 {}
>> 
>> 
>> Actually extending semantics (e.g. to extend Any or AnyObject) is a very 
>> large project that's out of scope. Without that, this is a small bit of 
>> syntactic sugar. 
>> 
>>   - Doug
>> 
>>> 
>>> On 22 Feb 2017, at 08:06, Jacob Bandes-Storch >> > wrote:
>>> 
 This works today:
 
 protocol P1{}
 protocol P2{}
 
 extension P1 where Self: P2 {
 func foo() {}
 }
 
 func bar(x: P1 & P2) {
 x.foo()
 }
 
 
 On Tue, Feb 21, 2017 at 10:53 PM, David Hart via swift-evolution 
 > wrote:
 Hello list,
 
 Found out yesterday that you can’t extend all existentials in Swift:
 
 protocol P1 {}
 extension P1 {}
 // works as expected
 
 protocol P2 {}
 extension P1 & P2 {}
 // error: non-nominal type 'P1 & P2' cannot be extended
 
 extension Any {}
 // error: non-nominal type 'Any' cannot be extended
 
 extension AnyObject {}
 // error: 'AnyObject' protocol cannot be extended
 
 I’d like to write a proposal to lift some of those restrictions. But the 
 question is: which should be lifted? P1 & P2 seems like an obvious case. 
 But what about Any and AnyObject? Is there a design reason that we 
 shouldn’t allow it?
 
 David.
 
 ___
 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

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


Re: [swift-evolution] [Fake-Proposal] Remove enums with associated objects

2017-02-21 Thread Slava Pestov via swift-evolution
One example is that in Java, it is difficult to distinguish a failed hashtable 
lookup from a hashtable lookup that produced a value of null. In Swift, these 
would be modeled as .none and .some(.none), respectively.

Slava


> On Feb 21, 2017, at 8:36 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
>> On Feb 20, 2017, at 10:34 PM, Tino Heth <2...@gmx.de> wrote:
>> 
>> Damn, there seems to be no better way to create reactions than saying 
>> something stupid ;-) - to bad the reactions tend to focus on the stupidity 
>> in this case...
>> It should have been "union" instead of "sum", so basically having 
>> Optional modeled as (T | Void)
> 
> This has been discussed several times in the past. If T is itself 
> Optional, then T | Void | Void == T | Void, meaning you can't safely use 
> Optional to model potential failure in any generic situation that could 
> itself produce Optional in normal circumstances. Having Optional 
> not exist may seem superficially easy, but generates a bunch of downstream 
> complexity, since you now need ad-hoc rules like "NSArrays can't contain 
> nil". It's no coincidence that so many languages grow multiple null-like 
> values in response to this situation—ObjC with NSNull; Javascript with null 
> and undef; VB with Null, Nothing, Missing, and None; and so on. The 
> parametric nature of sums makes it simpler to write correct generic code that 
> works uniformly in all circumstances. I get the sense that in most cases, 
> people are interested not in unions per se, since the proposed use cases 
> often involve disjoint types anyway. Specific affordances like subtyping, 
> cases-as-types, anonymous sum types, etc. could all potentially be added to 
> the sum type model to make them easier to use, and I agree that they could 
> potentially provide a better user experience than our current enum syntax, 
> but I think the basic language model is the correct one.
> 
> -Joe
> ___
> 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] Dictionary Enhancements

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 5:32 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
>> On Feb 16, 2017, at 5:17 PM, Ben Cohen > > wrote:
>> 
>> The win with mapping only the values is that the underlying hash table can 
>> retain the same physical layout, just with different values in the slots, so 
>> it can be done faster.
> 
> Only if the mapped dictionary’s values are the same type (or at least the 
> same size) as in the original dictionary, right? Would the proposed function 
> allow you to mapValues from a [K:V] to a [K:T]?

In both cases the key/bucket structure would be the same, I believe.

Slava

> 
> - Dave Sweeris
> ___
> 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] Support for pure functions. Part n + 1.

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 5:15 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
>> On Feb 16, 2017, at 3:13 PM, David Hart via swift-evolution 
>> > wrote:
>> 
>> Now that I've thought more about it, I have a question. Escaping/unescaping 
>> is an important concept to have in the language: if the API provider makes 
>> the promise that a closure is non-escaping, the API client doesn't have to 
>> worry about the closure capturing variables and creating strong references 
>> to them.
>> 
>> But in the case of pure functions, I fail to get the benefit from the 
>> examples. Could someone explain to me the advantages with a more in-depth 
>> example?
> 
> AFAIK, the two most direct benefits are memoization (without an “r”) and 
> concurrency. Because the everything the function does is contained within the 
> function itself and it can’t change or be affected by any global state, the 
> compiler can prove it’s ok to, for instance, parallelize a loop for you if 
> everything inside the loop is “pure". Additionally, because a pure function 
> will always give you the same output for the same input, you (or the 
> compiler, if it supports that level of optimization) can safely cache the 
> results of a function call in a Dictionary or something, and next time the 
> function is called do a quick lookup to see if you already know the answer 
> before passing the inputs along to the “real" function. The benefits of this 
> obviously depend on what the function is doing… it wouldn’t make sense to 
> cache simple integer addition, but if your function has, IDK, loops nested 23 
> levels deep and they all involve floating point division and matrix 
> multiplication or something, caching the answer will likely pay off.

I think memoization should be opt-in rather than something the compiler 
automatically infers. It has non-trivial time and space complexity tradeoffs, 
and I wouldn’t want the compiler making these decisions behind my back, or the 
behavior of a program changing between optimized and debug builds.

Slava

> 
> Here’s a article/site/blog/etc that talks about the more “quality of life” 
> kind of benefits: http://scalafp.com/book/benefits-of-pure-functions.html 
>  (note that some 
> people will vigorously contest the “easier to reason about” claim)
> 
> - Dave Sweeris
> ___
> 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] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 4:51 PM, Slava Pestov <spes...@apple.com> wrote:
> 
>> 
>> On Feb 16, 2017, at 4:50 PM, Slava Pestov <spes...@apple.com 
>> <mailto:spes...@apple.com>> wrote:
>> 
>>> 
>>> On Feb 16, 2017, at 4:44 PM, Slava Pestov via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> 
>>>> On Feb 16, 2017, at 4:37 PM, David Waite via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> 
>>>>> On Feb 16, 2017, at 4:28 PM, Matthew Johnson via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> As I have said elsewhere, I think the mental anguish mostly derives from 
>>>>> the fact that scoped private is not the right “default” in a language 
>>>>> that uses extensions pervasively.  Chris’s suggestion of having private 
>>>>> mean “same file *and* same type” would be a good default.  But if we’re 
>>>>> not willing to *also* have fileprivate then the Swift 2 definition of 
>>>>> private is the best “default’.  
>>>>> 
>>>>> I still think scoped access control is valuable but taking `private` as 
>>>>> the keyword for this was a mistake.  I’d like to see us take another stab 
>>>>> at identifying a suitable name for it.  That said, I get the feeling that 
>>>>> not too many others have appetite for this so it may be a lost cause…
>>>> 
>>>> My opinion is that a file level grouping is fine, but that people want a 
>>>> level between that and internal. They want to have subsystems. In Swift 2, 
>>>> the only level below framework-wide was the fileprivate-style scope, which 
>>>> had the potential to encourage lots of interrelated code to be grouped 
>>>> within a single source file. 
>>> 
>>> Is it really necessary to encode this subsystem grouping in a way that can 
>>> be checked by the compiler though, instead of enforcing it with coding 
>>> conventions?
>>> 
>>> Slava
>> 
>> It’s also worth pointing out that private/fileprivate have been a constant 
>> source of implementation issues:
>> 
>> - They do not have a stable mangled name, and cannot be serialized in a 
>> meaningful way
>> - The ‘private descriminator’ adds complexity to serialization and mangling 
>> in general
> 
> This is confusing — in the first case I’m talking about serialization as in 
> NSCoding, in the second I’m referring to .swiftmodule file generation in the 
> compiler.

Oh and of course just the logic for the actual accessibility checking in Sema 
is a bit scary now. There were holes in the implementation in Swift 3, so now 
Swift 3.1 has to simulate the old quirks, but emit warnings in Swift 3 mode, 
and emit errors in Swift 4 mode.

Slava

> 
> Slava
> 
>> - Slightly different linking behavior in WMO and non-WMO builds
>> - Textual SIL cannot use them, which together with the above blocks the 
>> stdlib from adopting ‘private'
>> 
>> I’m sure there are others. There’s an opportunity cost to keeping quirky 
>> features around and adding new ones — it prevents us from being able to 
>> spend more time on improvements that actually matter, such as compile time, 
>> crashes and diagnostics.
>> 
>> Slava
>> 
>>> 
>>>> 
>>>> -DW
>>>> 
>>>> ___
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <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] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 4:50 PM, Slava Pestov <spes...@apple.com> wrote:
> 
>> 
>> On Feb 16, 2017, at 4:44 PM, Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Feb 16, 2017, at 4:37 PM, David Waite via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> 
>>>> On Feb 16, 2017, at 4:28 PM, Matthew Johnson via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> As I have said elsewhere, I think the mental anguish mostly derives from 
>>>> the fact that scoped private is not the right “default” in a language that 
>>>> uses extensions pervasively.  Chris’s suggestion of having private mean 
>>>> “same file *and* same type” would be a good default.  But if we’re not 
>>>> willing to *also* have fileprivate then the Swift 2 definition of private 
>>>> is the best “default’.  
>>>> 
>>>> I still think scoped access control is valuable but taking `private` as 
>>>> the keyword for this was a mistake.  I’d like to see us take another stab 
>>>> at identifying a suitable name for it.  That said, I get the feeling that 
>>>> not too many others have appetite for this so it may be a lost cause…
>>> 
>>> My opinion is that a file level grouping is fine, but that people want a 
>>> level between that and internal. They want to have subsystems. In Swift 2, 
>>> the only level below framework-wide was the fileprivate-style scope, which 
>>> had the potential to encourage lots of interrelated code to be grouped 
>>> within a single source file. 
>> 
>> Is it really necessary to encode this subsystem grouping in a way that can 
>> be checked by the compiler though, instead of enforcing it with coding 
>> conventions?
>> 
>> Slava
> 
> It’s also worth pointing out that private/fileprivate have been a constant 
> source of implementation issues:
> 
> - They do not have a stable mangled name, and cannot be serialized in a 
> meaningful way
> - The ‘private descriminator’ adds complexity to serialization and mangling 
> in general

This is confusing — in the first case I’m talking about serialization as in 
NSCoding, in the second I’m referring to .swiftmodule file generation in the 
compiler.

Slava

> - Slightly different linking behavior in WMO and non-WMO builds
> - Textual SIL cannot use them, which together with the above blocks the 
> stdlib from adopting ‘private'
> 
> I’m sure there are others. There’s an opportunity cost to keeping quirky 
> features around and adding new ones — it prevents us from being able to spend 
> more time on improvements that actually matter, such as compile time, crashes 
> and diagnostics.
> 
> Slava
> 
>> 
>>> 
>>> -DW
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 4:44 PM, Slava Pestov via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> 
>> On Feb 16, 2017, at 4:37 PM, David Waite via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Feb 16, 2017, at 4:28 PM, Matthew Johnson via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> As I have said elsewhere, I think the mental anguish mostly derives from 
>>> the fact that scoped private is not the right “default” in a language that 
>>> uses extensions pervasively.  Chris’s suggestion of having private mean 
>>> “same file *and* same type” would be a good default.  But if we’re not 
>>> willing to *also* have fileprivate then the Swift 2 definition of private 
>>> is the best “default’.  
>>> 
>>> I still think scoped access control is valuable but taking `private` as the 
>>> keyword for this was a mistake.  I’d like to see us take another stab at 
>>> identifying a suitable name for it.  That said, I get the feeling that not 
>>> too many others have appetite for this so it may be a lost cause…
>> 
>> My opinion is that a file level grouping is fine, but that people want a 
>> level between that and internal. They want to have subsystems. In Swift 2, 
>> the only level below framework-wide was the fileprivate-style scope, which 
>> had the potential to encourage lots of interrelated code to be grouped 
>> within a single source file. 
> 
> Is it really necessary to encode this subsystem grouping in a way that can be 
> checked by the compiler though, instead of enforcing it with coding 
> conventions?
> 
> Slava

It’s also worth pointing out that private/fileprivate have been a constant 
source of implementation issues:

- They do not have a stable mangled name, and cannot be serialized in a 
meaningful way
- The ‘private descriminator’ adds complexity to serialization and mangling in 
general
- Slightly different linking behavior in WMO and non-WMO builds
- Textual SIL cannot use them, which together with the above blocks the stdlib 
from adopting ‘private'

I’m sure there are others. There’s an opportunity cost to keeping quirky 
features around and adding new ones — it prevents us from being able to spend 
more time on improvements that actually matter, such as compile time, crashes 
and diagnostics.

Slava

> 
>> 
>> -DW
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 15, 2017, at 1:34 AM, Dietmar Planitzer via swift-evolution 
>  wrote:
> 
> I do like approach #2. It would play well with extensions, look very familiar 
> to how private works in other main stream languages and it wouldn’t get in 
> the way of a possible future refinement of extensions to this model:
> 
> a) 1st party extension (extension defined and owned by the type owner): 
> extension is defined in the same module as the base type:
> 
> - allows access to private type properties and functions even if the base 
> type and extension are in different files
> - allows the definition of stored properties for value and class types

These are still problematic if the extension is in a different file than the 
original type (even if they’re in the same module) when you’re not compiling 
with WMO.

I’d rather not allow this.

Slava

> 
> b) 3rd party extension (extension is defined and owned by the _user_ of a 
> type): extension is defined in a parent module and the base type is defined 
> in a sub-module:
> 
> - forbids access to private properties and functions from the imported type
> - forbids the definition of stored properties for value types
> - MAY allow the definition of stored properties on class types (haven’t 
> really convinced myself that this would be a good idea)
> 
> “parent module” would either mean the application that links against a module 
> (what is supported today) but also the parent module of a sub-module 
> (potential future addition).
> 
> 
> Regards,
> 
> Dietmar Planitzer
> 
> 
>> On Feb 14, 2017, at 21:31, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Feb 14, 2017, at 3:20 AM, David Hart  wrote:
>>> 
>>> 
>>> On 14 Feb 2017, at 09:25, Goffredo Marocchi  wrote:
>>> 
 I disagree with that as well as I still think we are damaging the language 
 each time we take a known concept (like access levels) and give new 
 meanings to the same keywords. I still look baffled at the redefinition of 
 do and the addition of repeat for example...
 
 Private, the way it was before, was an admittedly curious take on how most 
 languages mean by private and we have jumped through a lot of hoops to 
 justify why we did not start with Java/C++/C# like access control and 
 augmented it instead of redefining things, omitting others, and then 
 constantly pulling the language left and right with not a lot of permanent 
 consensus either way as this discussion and others before show.
>>> 
>>> It's a curious take, but it is a curious take is perfectly coherent with 
>>> Swift extensions. How else would you access private implementation details 
>>> from an extension? But putting it in the same file, instead of having to 
>>> resort to an internal access level.
>> 
>> Right.  Swift is its own language distinct from Java/C++/etc.  While it is 
>> intentionally designed to remain familiar (and thus reuses many keywords 
>> across the language family), it often does so with slightly different 
>> meaning / behavior.  Consider ‘throw’ for example.
>> 
>> Keeping with the spirit of Swift and staying consistent with its design, I 
>> see two plausible meanings for private:
>> 
>> Private could mean either:
>> 1) private to the file (Swift 2 semantics)
>> 2) accessible only to the current type/scope and to extensions to that type 
>> that are in the current file.
>> 
>> I don’t think we’ve ever evaluated and debated approach #2 systematically.
>> 
>> -Chris
>> 
>> ___
>> 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] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution

> On Feb 16, 2017, at 4:37 PM, David Waite via swift-evolution 
>  wrote:
> 
> 
>> On Feb 16, 2017, at 4:28 PM, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>> As I have said elsewhere, I think the mental anguish mostly derives from the 
>> fact that scoped private is not the right “default” in a language that uses 
>> extensions pervasively.  Chris’s suggestion of having private mean “same 
>> file *and* same type” would be a good default.  But if we’re not willing to 
>> *also* have fileprivate then the Swift 2 definition of private is the best 
>> “default’.  
>> 
>> I still think scoped access control is valuable but taking `private` as the 
>> keyword for this was a mistake.  I’d like to see us take another stab at 
>> identifying a suitable name for it.  That said, I get the feeling that not 
>> too many others have appetite for this so it may be a lost cause…
> 
> My opinion is that a file level grouping is fine, but that people want a 
> level between that and internal. They want to have subsystems. In Swift 2, 
> the only level below framework-wide was the fileprivate-style scope, which 
> had the potential to encourage lots of interrelated code to be grouped within 
> a single source file. 

Is it really necessary to encode this subsystem grouping in a way that can be 
checked by the compiler though, instead of enforcing it with coding conventions?

Slava

> 
> -DW
> 
> ___
> 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] [Review] SE-0155: Normalize Enum Case Representation

2017-02-18 Thread Slava Pestov via swift-evolution
+1, two small questions:

- If two cases have the same base name but different full names, will matching 
on the base name match both cases, or will it be an error?
- What are the memory layout optimizations described here? From a first glance 
this looks purely syntactic.

Slava

> On Feb 17, 2017, at 7:26 PM, John McCall via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0155: Normalize Enum Case Representation" begins now and 
> runs through next Friday, February 26th. The proposal is available here:
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
>   https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
>   Proposal link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md
>  
> 
> 
>   Reply text
> 
>   Other replies
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   • What is your evaluation of the proposal?
>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   • Does this proposal fit well with the feel and direction of Swift?
>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at 
> https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> 
> Thank you,
> 
> John McCall
> Review Manager
> ___
> 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] Overloading Generic Types

2017-02-22 Thread Slava Pestov via swift-evolution

> On Feb 22, 2017, at 1:22 PM, David Sweeris via swift-evolution 
>  wrote:
> 
>> 
>> On Feb 22, 2017, at 12:21 PM, Huon Wilson > > wrote:
>> 
>> 
>>> On Feb 22, 2017, at 10:20, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> What if we extended that to any type that’s ExpressibleByNilLiteral & 
>>> Equatable?
>> 
>> Note that this is not how the Unsafe*Pointer optimization works: in that 
>> case, the type Unsafe*Pointer is not ExpressibleByNilLiteral, it just has 
>> some spare/guaranteed-to-be-unused sentinel values in its representation, 
>> that the compiler knows about. This also works for types like `enum X { case 
>> A, B }`: an optional like X? (and X??, all the way up to 254 ?’s) is also 
>> represented as a single byte, because there’s spare values that the compiler 
>> knows won't be used by valid instances of X.
>> 
>> Converting valid instances  to .none would break round-tripping: 
>> Optional(x)! would sometimes fail, if x was the sentinel value. This seems 
>> likely to cause generic code to stop working.
> 
> Oh, hey, yeah, good point! I should’ve thought about that bit more first. 
> Would a `HasInvalidBitPattern` protocol work? 

This is basically how the optional payload optimization works behind the 
scenes. It’s not specific to optional, or having a certain payload type, it 
works for other enums also.

IRGen knows for each builtin type, what the valid and invalid bit patterns are. 
Basically reference types and unsafe pointers are the ones that are known to 
have invalid bit patterns (nulls, and for references, we also know the least 
significant 3 bits are always zero because of alignment). From this it can 
compute the valid and invalid bit patterns of tuple types and structs that 
appear in enum payloads also.

Slava

> protocol HasInvalidBitPattern {
> /// An unreachable bit pattern. Very Bad Things are very likely to happen 
> if this represents a valid value.
> static var invalidBitPattern: Self {get} // probably use some private 
> init to create this, or some other mechanism that doesn’t get exposed to the 
> client
> }
> Then, the special-case Optional definition would be:
> enum Optional : ExpressibleByNilLiteral where T: HasInvalidBitPattern & 
> Equatable {
> case some(T)
> init(_ value: T) { self = .some(value) }
> init(nilLiteral: ()) { self = .some(T.invalidBitPattern) }
> var case none: (matches: Bool, associatedValue: Void) {
> switch self {
> case .some(let value): return (value == T.invalidBitPattern, ())
> }
> }
> }
> 
>> Example program for the enum optimization:
>> 
>> enum X {
>> case A, B
>> }
>> 
>> typealias O2 = T??
>> typealias O4 = O2
>> typealias O8 = O4
>> typealias O16 = O8
>> typealias O32 = O16
>> typealias O64 = O32
>> typealias O128 = O64
>> typealias O256 = O128
>> 
>> typealias O254 = O128>
>> typealias O255 = O254?
>> 
>> func size(_: T.Type) -> Int {
>> return MemoryLayout.size
>> }
>> 
>> print(size(X.self), // 1
>>   size((X?).self), // 1
>>   size(O254.self), // 1
>>   size(O255.self), // 2
>>   size(O256.self)) // 3
>> 
>> (The last is 3 because the compiler currently essentially treats O255 
>> like an opaque/all-values-valid 2-byte type, like Int16, and so adds an 
>> extra byte for the extra ?. It could theoretically be 2 if the unused values 
>> in the extra byte in O255 are reused.)
> 
> That’s quite interesting, thanks!
> 
> - Dave Sweeris
> ___
> 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] final + lazy + fileprivate modifiers

2017-02-22 Thread Slava Pestov via swift-evolution

> On Feb 21, 2017, at 4:19 PM, David Waite via swift-evolution 
>  wrote:
> 
> 
>> On Feb 21, 2017, at 2:27 AM, Joanna Carter  
>> wrote:
>> 
>> But in the Swift world, we now have the ability to extend almost any type, 
>> except Any and AnyObject, which appear to be protected by some deep and dark 
>> mechanism within the compiler.  So, just as those two protocols cannot be 
>> extended, should we not be looking at some generally available mechanism to 
>> prevent extensibility of any type?
>> 
>> And, I am not talking visibility here, just extensibility ; somehow those 
>> two concerns are often conflated and, I believe, this is the cause of much 
>> of the "lively" discussion on visibility specifiers.
> 
> This is imho more of an issue with ABI and resiliency. If I can create an 
> extension which adds a method to a type, and that type gains a method with 
> that same signature in a later release, what is the behavior?

Extension methods are lexically scoped and statically dispatched, so existing 
code will not be affected by the addition of the new method. New code will call 
whichever method is visible, or if both are visible in a given lexical scope 
and overload resolution rules cannot pick an unambiguous winner, the code will 
no longer type check.

The situation is messier with extensions that add protocol conformances. Right 
now we don’t do a good job of dealing with duplicate conformances because we 
assume in several places in the compiler and runtime that they can be looked up 
globally. We plan on addressing at least some of this.

Slava

> 
>> 
>>> In C++ terms, it would be when I want some other class to have friend 
>>> access to a function/data, but for it not to be arbitrarily accessible by 
>>> subtypes
>> 
>> Indeed. I do wonder if some folks approach visibility control as an exercise 
>> in "what can I see" whereas, demonstrated by C++ friends, it becomes obvious 
>> that it is more about "what do I want to allow to be seen"
>> 
>> Is there not a value in forking this discussion into which keywords are 
>> truly about visibility control and which are about extensibility control?
> 
> Possibly; they are two axes. However, I’m hoping that new access modifiers 
> (including possible submodule functionality) + extensibility modifiers are 
> considered holistically. 
> 
> For instance, if there is a feature that allows something comparable to 
> ‘friend’ level access, a restrictive private makes a lot more sense than one 
> with exceptions allowing access to subtypes, within the same file, to 
> extensions, etc. A restrictive, scoped private would be what you use to 
> protect the invariants of your type, with less protected methods given to 
> allow extensions and internal modification safely.
> 
> But without a submodule or similar access level, we need a “fileprivate” 
> level access (renamed to ‘private’ or not) to make sure code needing a higher 
> level of access can get it, by being embedded in the same file.
> 
>> OK, how does this sound?
>> 
>> Extend the 'final' concept, currently used only in classes, to protect any, 
>> non-protocol, type from being extended.
> 
> The extension mechanism, both being able to add new methods and to conform an 
> existing class to a protocol retroactively, is absurdly powerful. It doesn’t 
> offer any privileged manipulation of types today that would give a safety 
> related reason to restrict it. I’d be reluctant to let someone take that away 
> from me personally without a strong language-level justification (such as 
> needing to restrict it partially to meet ABI/resiliency requirements)
> 
> -DW
> ___
> 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] Overloading Generic Types

2017-02-22 Thread Slava Pestov via swift-evolution

> On Feb 22, 2017, at 3:39 PM, David Sweeris  wrote:
> 
>> 
>> On Feb 22, 2017, at 3:00 PM, Slava Pestov > > wrote:
>> 
>> 
>>> On Dec 23, 2016, at 12:32 PM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
>>> (I feel like I’ve already written this... I looked through my sent mail and 
>>> didn’t see anything, but my sincerest apologies if I started this thread a 
>>> month ago and forgot about it or something.)
>>> 
>>> I no longer recall exactly what first made me want to do this (probably 
>>> something in my on-going “teach the compiler calculus” project), but I’ve 
>>> been thinking lately that it could be quite handy to overload types 
>>> themselves based on the value of generic parameters. As a somewhat 
>>> contrived example:
>>> struct Array  { /*everything exactly as it is now*/ }
>>> struct Array  where T == Bool { /* packs every 8 bools into a UInt8 for 
>>> more efficient storage */ }
>>> 
>>> We can already do this with functions… Conceptually this isn’t any 
>>> different.
>> 
>> Actually this is a major complication because of the runtime generics model. 
>> Imagine you have a function that takes a T and constructs an Array. Now 
>> it has to do dynamic dispatch to find the right type metadata (is it the 
>> “generic” Array, or the specialized Array?)
> 
> Wouldn’t that get resolved at compile time? Oh! Wait, are you talking about 
> this?
> func bar  (_ x: T) -> String { return "any T" }
> func bar  (_ x: T) -> String where T: CustomStringConvertible { return 
> "\(x)" }
> func foo  (_ x: T) -> String { return bar(x) }
> and “foo()" always returns “any T” because by the time we get to `bar`, T 
> isn’t known to be constrained to anything at compile time?

I mean this:

func foo(t: T) -> [T] {
  return [t]
}

foo(t: false) // is this the ‘optimized’ or ‘unoptimized’ version?
foo(t: 123)

> 
> In any case, since the point is to optimize the type's implementation rather 
> than change its behavior, I think the only result is that your array maker 
> function would return an “unoptimized” array.

Ok then, what if I have:

func foo(x: T, y: T) {

}

And I call foo() with an ‘optimized’ Array and ‘unoptimized’ Array. 
That won’t work at all, since it’s only passing one type metadata parameter for 
T, and not one for each value. So which one would it pass?

> I’m not sure… I’d have to think about it some more. And come up with a better 
> illustration, since it’s been pointed out that my original example isn’t a 
> particularly good idea.
> 
>>> As long as the specific version exposes everything the generic version does 
>>> (easy for the compiler to enforce), I think everything would just work 
>>> (famous last words).
>> 
>> What if another module defines an extension of Array, but not ‘Array 
>> where T == Bool’?
> 
> IIUC, that shouldn’t matter because the specific version would have to have 
> the same public interface as the generic version.

But with the extension in place, now they have different interfaces, because 
the optimized version won’t have the extension’s methods in it.

> 
>>> In this example, the subscript function would need to extract the specified 
>>> bit and return it as a Bool instead of simply returning the specified 
>>> element. The `Element` typealias would be `Bool` instead of `UInt8`, which 
>>> would mean the size/stride might be different than expected (but that’s why 
>>> we have `MemoryLayout<>`).
>>> 
>>> Anyway, because generic structs & functions already can’t make assumptions 
>>> about a generic argument (beyond any constraints, of course), I think this 
>>> should be in phase 2… but I’m quite hazy on how generics work once the 
>>> code’s been compiled, so maybe not.
>> 
>> Another way of modeling this might be to define a protocol, say 
>> “RepresentableInArray”, which implements get and set methods that take a 
>> pointer to a buffer, and an index. A default implementation in a protocol 
>> extension would just load and store the value. ‘Bool’ would define its own 
>> conformance which performs bitwise operations.
>> 
>> However I think this is out of scope for stage 2 — it doesn’t fix any 
>> obvious major shortcoming in the language, it vastly complicates the 
>> implementation and it’s not required to achieve our ABI stability goals.
> 
> Fair enough. Is there a stage 3, or does that mean “out of scope until Swift 
> 4.1+”?

The latter.

Slava

> 
> - Dave Sweeris

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


Re: [swift-evolution] Overloading Generic Types

2017-02-22 Thread Slava Pestov via swift-evolution

> On Dec 23, 2016, at 12:32 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> (I feel like I’ve already written this... I looked through my sent mail and 
> didn’t see anything, but my sincerest apologies if I started this thread a 
> month ago and forgot about it or something.)
> 
> I no longer recall exactly what first made me want to do this (probably 
> something in my on-going “teach the compiler calculus” project), but I’ve 
> been thinking lately that it could be quite handy to overload types 
> themselves based on the value of generic parameters. As a somewhat contrived 
> example:
> struct Array  { /*everything exactly as it is now*/ }
> struct Array  where T == Bool { /* packs every 8 bools into a UInt8 for 
> more efficient storage */ }
> 
> We can already do this with functions… Conceptually this isn’t any different.

Actually this is a major complication because of the runtime generics model. 
Imagine you have a function that takes a T and constructs an Array. Now it 
has to do dynamic dispatch to find the right type metadata (is it the “generic” 
Array, or the specialized Array?)

> As long as the specific version exposes everything the generic version does 
> (easy for the compiler to enforce), I think everything would just work 
> (famous last words).

What if another module defines an extension of Array, but not ‘Array 
where T == Bool’?

> In this example, the subscript function would need to extract the specified 
> bit and return it as a Bool instead of simply returning the specified 
> element. The `Element` typealias would be `Bool` instead of `UInt8`, which 
> would mean the size/stride might be different than expected (but that’s why 
> we have `MemoryLayout<>`).
> 
> Anyway, because generic structs & functions already can’t make assumptions 
> about a generic argument (beyond any constraints, of course), I think this 
> should be in phase 2… but I’m quite hazy on how generics work once the code’s 
> been compiled, so maybe not.

Another way of modeling this might be to define a protocol, say 
“RepresentableInArray”, which implements get and set methods that take a 
pointer to a buffer, and an index. A default implementation in a protocol 
extension would just load and store the value. ‘Bool’ would define its own 
conformance which performs bitwise operations.

However I think this is out of scope for stage 2 — it doesn’t fix any obvious 
major shortcoming in the language, it vastly complicates the implementation and 
it’s not required to achieve our ABI stability goals.

Slava

> 
> - Dave Sweeris
> 
> ___
> 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] A concern

2017-02-19 Thread Slava Pestov via swift-evolution

> On Feb 19, 2017, at 1:00 AM, Rien via swift-evolution 
>  wrote:
> 
> Hello All,
> 
> Its Sunday, time for some reflection...
> 
> One of the big plusses of Objective-C was that the entire manual was just a 
> few pages long. I have not looked it up, but IIRC the entire manual 
> describing the language was probably less than 50 pages. Much less if you 
> subtract the filler stuff.

If you add the size of the C specification, Objective-C is actually a very 
large language, with all kinds of quirks and undefined behavior. Most people 
coming to Objective-C already have some familiarity with C-like languages 
though, so I think this aspect is forgotten sometimes.

> I have been on this list now for a few weeks, and I see very little push-back 
> on new suggestions. Most of the reactions are positive-constructive. IMO we 
> need more push-back. Without it behemoth status is all but guaranteed.
> 
> I don’t know about the core team, I don’t know about Apple, I don’t know 
> where they want to go.

I think it is good and healthy that all kinds of outlandish ideas get discussed 
on this list; even if they never end up getting implemented — the discussions 
further mutual understanding and inspire better ideas in the future. It 
wouldn’t be productive for us to just unilaterally shut down such discussions.

Remember there’s a long road from “pitching an idea” to “core team accepts a 
proposal”. The bar for proposals accepted into Swift 4 is considerably higher; 
think of it as, “without this proposal, the language is fundamentally broken 
for an important use-case”.

Also I think one important quality of the Swift design is “progressive 
disclosure”. There are some advanced features, but they are layered on in such 
a way that one does not need to absorb most of them in order to be productive 
in the language. They can be learned over time. This is unlike, say, C++, where 
a lot of complexity has to be understood up-front before you can really write 
good modern C++.

It’s not necessarily a bad thing if a well-designed language with advanced 
features and a large standard library has a big manual.

> I just want to make a plea here: Please stop Swift from becoming a behemoth.

As someone who admires small languages like Scheme, Smalltalk, Forth and ML, I 
can assure you that your point of view has its proponents here ;-) And I think 
the core team has very good taste when it comes to these things as well.

Slava

> 
> I don’t know if the millions (?) of Swift developers not on this list agree 
> with me. I somehow think they do, after all they are not on this list! They 
> are not looking to change Swift...
> 
> Well, I just had to get that off my chest...
> 
> To close this off, I do want to take this opportunity to thank the core team 
> for their work, I truly appreciate it!
> And whatever may come, here is one happy Swift user!
> 
> Best regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl
> 
> 
> 
> 
> 
> ___
> 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/Reality Check] Allow instance members as parameter default values

2017-02-22 Thread Slava Pestov via swift-evolution
I think this is a manifestation of a more general problem, that default 
arguments cannot capture values from outer scope. Saying they’re evaluated in 
“type context” and not “instance context” is one way to skirt around the issue, 
but you can still trigger capturing anyway, and crash in SILGen:

public func foo() {
  let x = 10

  func bar(y: Int = x) {}
}

Fixing this would not be too difficult, just refactoring some code in Sema so 
that we actually compute the captures of each default argument generator, and 
then emit the captures when we call one.

Slava

> On Feb 22, 2017, at 10:16 AM, Nate Cook via swift-evolution 
>  wrote:
> 
> Hello all,
> 
> I was surprised to find that I can't use an instance member as the default 
> value of a method parameter, only constants and the run-time calculated 
> #file, #line, etc. Is it possible to remove this limitation?
> 
> I'd like to propose that we add an overload of the collection 
> index(_:offsetBy:) methods that use the collection's startIndex as a default 
> parameter, but we can't provide that without either this feature or an extra 
> overload. If the declaration looks like this:
> 
> extension Collection {
> func index(_ i: Index = startIndex, offsetBy n: IndexDistance) -> Index {
> // ...
> }
> }
> 
> then calling that method with an omitted first parameter would treat it as 
> something like this:
> 
> extension Collection {
> func index(offsetBy n: IndexDistance) -> Index {  
> let i = startIndex
> // ...
> }
> }
> 
> Is this just syntactic sugar, or am I missing something that makes this 
> harder than it looks? I can see how more complex expressions could be useful 
> there, too, and can't find an obvious reason we couldn't use any code that 
> could be inserted at the top of the method body.
> 
> Thanks!
> Nate
> 
> ___
> 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] consistent public access modifiers

2017-02-12 Thread Slava Pestov via swift-evolution

> On Feb 11, 2017, at 2:41 PM, Karl Wagner via swift-evolution 
>  wrote:

> For example, the compiler squashes the layout of an enum in to the smallest 
> type which can represent all of its cases - so if you only have 2 cases, your 
> enum will be an Int1 (possibly stored in a way which overlaps the payload, if 
> there are spare bits to do so).

This is still the case with resilient enums. The current implementation of 
resilient value types does not change the memory layout of those types. Rather, 
it makes clients access the values indirectly, using a value witness table 
instead of making assumptions about the size, etc.

> 
> If we introduce some kind of forwards-compatible enum, it should explicitly 
> be something different (like an “open” enum). It’s the nichest of 
> niche-cases, would change the layout and prohibit optimisations, and make 
> those objects more difficult to reason about.

Perhaps, but note that resilience does *not* prohibit layout optimizations — 
instead, it means that clients use an indirect access pattern where knowledge 
of the layout is encapsulated in the library.

Slava

> 
>> 
>>>  
 3. In Swift 5, upgrade the warning to an error for non-exhaustiveness if a 
 switch statement over a public enum doesn't have a `default` statement. 
 Now, new syntax to extend an `open enum` can be introduced and the 
 compiler can treat closed and public enums differently.
>>> 
>>> If the community and core team support this strategy I will also.  It seems 
>>> reasonable and speeds up the transition by using the point release.  That's 
>>> a great idea!
>>> 
>> 
>> ___
>> 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] final + lazy + fileprivate modifiers

2017-02-13 Thread Slava Pestov via swift-evolution

> On Feb 12, 2017, at 8:19 AM, David Hart via swift-evolution 
>  wrote:
> 
> I was reading this nice listing of Swift keywords 
> (https://medium.com/the-traveled-ios-developers-guide/swift-keywords-v-3-0-1-f59783bf26c#.2s2yis3zh
>  
> )
>  and three of them struck me as potentially not long for this world and I was 
> thinking if we needed/could deprecate them before any kind of ABI stability 
> set in.
> 
> I'm listing them here but it might be worth starting separate discussions for 
> each of them.
> 
> Final
> 
> Can someone tell me what is the use of 'final' now that we have 'public' 
> default to disallowing subclassing in importing modules? I know that 'final' 
> has the added constraint of disallowing subclassing in the same module, but 
> how useful is that? Does it hold its weight? Would we add it now if it did 
> not exist?

Adding or removing ‘final’ on a non-open class, or members of a non-open class, 
will not change ABI.

Slava

> 
> Lazy
> 
> This one is clearer: if Joe Groff's property behaviors proposal from last 
> year is brought forward again, lazy can be demoted from a language keyword to 
> a Standard Library property behavior. If Joe or anybody from the core team 
> sees this: do we have any luck of having this awesome feature we 
> discussed/designed/implemented in the Swift 4 timeframe?
> 
> Fileprivate 
> 
> I started the discussion early during the Swift 4 timeframe that I regret the 
> change in Swift 3 which introduced a scoped private keyword. For me, it's not 
> worth the increase in complexity in access modifiers. I was very happy with 
> the file-scope of Swift pre-3. When discussing that, Chris Latner mentioned 
> we'd have to wait for Phase 2 to re-discuss it and also show proof that 
> people mostly used 'fileprivate' and not the new 'private' modifier as proof 
> if we want the proposal to have any weight. Does anybody have a good idea for 
> compiling stats from GitHub on this subject? First of all, I've always found 
> the GitHub Search quite bad and don't know how much it can be trusted. 
> Secondly, because 'private' in Swift 2 and 3 have different meanings, a 
> simple textual search might get us wrong results if we don't find a way to 
> filter on Swift 3 code.
> 
> Thanks for hearing me out!
> 
> David.
> ___
> 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] Class and Subclass Existentials (Round 2)

2017-02-14 Thread Slava Pestov via swift-evolution

> On Feb 14, 2017, at 1:30 AM, Adrian Zubarev <adrian.zuba...@devandartist.com> 
> wrote:
> 
> Why can’t we completely ban this?
> 
> protocol A {}
> protocol B {}
> typealias AB = A & B
> 
> protocol C : AB {} // Allowed, but could be also banned
> 
> protocol D : A & B {} // Error
> 

I didn’t even know the last one there was banned. /me hangs head in shame.

I think either both should be supported, or neither one should be supported. 
I’m leaning toward the former :-)

However note that unlike protocols that inherit from classes, this does not 
create any conceptual difficulties in the language; it’s merely a syntactic 
quirk. I’m more concerned about banning protocols that inherit from typealiases 
that contain classes.

Slava

> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 14. Februar 2017 um 10:25:43, Slava Pestov via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> 
>>> On Feb 12, 2017, at 12:32 PM, David Hart via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi Matthew,
>>> 
>>> Your arguments made sense to me. I modified the proposal to choose strategy 
>>> number 3: deprecating and removing class over several versions to favour 
>>> AnyObject. Mind having another proof read?
>>> 
>>> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md
>>>  
>>> <https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md>
>>> 
>>> Anybody has counter arguments?
>>> 
>>> Class and Subtype existentials
>>> Proposal: SE- 
>>> <https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md>
>>> Authors: David Hart <http://github.com/hartbit/>, Austin Zheng 
>>> <http://github.com/austinzheng>
>>> Review Manager: TBD
>>> Status: TBD
>>>  
>>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials#introduction>Introduction
>>> 
>>> This proposal brings more expressive power to the type system by allowing 
>>> Swift to represent existentials of classes and subtypes which conform to 
>>> protocols.
>>> 
>>>  
>>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials#motivation>Motivation
>>> 
>>> Currently, the only existentials which can be represented in Swift are 
>>> conformances to a set of protocols, using the  composition syntax:
>>> 
>>> Protocol1 & Protocol2
>>> On the other hand, Objective-C is capable of expressing existentials of 
>>> classes and subclasses conforming to protocols with the following syntax:
>>> 
>>> id<Protocol1, Protocol2>
>>> Base*
>>> We propose to provide similar expressive power to Swift, which will also 
>>> improve the bridging of those types from Objective-C.
>>> 
>>>  
>>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials#proposed-solution>Proposed
>>>  solution
>>> 
>>> The proposal keeps the existing & syntax but allows the first element, and 
>>> only the first, to be either the AnyObjectkeyword or of class type. The 
>>> equivalent to the above Objective-C types would look like this:
>>> 
>>> AnyObject & Protocol1 & Protocol2
>>> Base & Protocol
>>> As in Objective-C, the first line is an existential of classes which 
>>> conform to Protocol1 and Protocol2, and the second line is an existential 
>>> of subtypes of Base which conform to Protocol.
>>> 
>>> Here are the new proposed rules for what is valid in a existential 
>>> conjunction syntax:
>>> 
>>>  
>>> <https://github.com/hartbit/swift-evolution/tree/subclass-existentials#1-the-first-element-in-the-protocol-composition-syntax-can-be-the-anyobject-keyword-to-enforce-a-class-constraint>1.
>>>  The first element in the protocol composition syntax can be the AnyObject 
>>> keyword to enforce a class constraint:
>>> 
>>> protocol P {}
>>> struct S : P {}
>>> class C : P {}
>>> let t: P & AnyObject // Compiler error: AnyObject requirement must be in 
>>> first position
>>> let u: AnyObject & P = S() // Compiler error: S is not of class type
>>> let v: AnyObject & P = C() // 

Re: [swift-evolution] final + lazy + fileprivate modifiers

2017-02-14 Thread Slava Pestov via swift-evolution

> On Feb 13, 2017, at 6:50 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> Personally I’d prefer if we all together with the core team set down 
> (virtually ^^) and:
> 
> Fully re-evaluated all the access modifier mess and sketched a new future 
> oriented model on how this should have been regardless it’s breaking change 
> or not.
> Communicated the corrected model with the community.
> Only after #2 we should made a decision on how to proceed.
> The reason I see this that way, because some part of the language seems to be 
> a rushed mistake that everyone should now live with, just because we seek for 
> ABI stability, we are unable to build a rocket, because our hands are tied.
> 
> 

I’m not sure any of this is really blocking ABI stability. By definition, only 
public declarations affect ABI.

Slava
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 13. Februar 2017 um 15:30:20, David Hart (da...@hartbit.com 
> ) schrieb:
> 
>> Very good graphic. But it reinforces my opinion that it's currently more 
>> messy/complicated than I should be. It looks like an over-designed or 
>> designed-by-comitee model. I understand that private is useful, but not 
>> useful enough to warrant the increased complexity. My 2 cents.
>> 
>> On 13 Feb 2017, at 15:25, Adrian Zubarev via swift-evolution 
>> > wrote:
>> 
>>> I actually made a small visual of how open vs. public should work 
>>> constantly on twitter: 
>>> https://twitter.com/DevAndArtist/status/829688528216924160 
>>> 
>>> 
>>> 
>>> 
>>> -- 
>>> Adrian Zubarev
>>> Sent with Airmail
>>> 
>>> Am 13. Februar 2017 um 15:20:10, Matthew Johnson via swift-evolution 
>>> (swift-evolution@swift.org ) schrieb:
>>> 
 
 
 Sent from my iPad
 
 > On Feb 13, 2017, at 1:35 AM, Rien via swift-evolution 
 > > wrote:
 >
 >
 >> On 13 Feb 2017, at 06:16, Derrick Ho via swift-evolution 
 >> > wrote:
 >>
 >> I think I we can live with the original three: public, internal, and 
 >> private
 >>
 >> Where public is visible to all,
 >> Internal is visible to all within the module, and private is visible 
 >> only to the class and the same file.
 >>
 >> We can still fulfill the same roles that the current five fill.
 >>
 >> Open can become public again.
 >> Public can become final public
 
 This is incorrect. The way `public` behaves today is very different than 
 `final public`. Today it only restricts clients of a library from 
 subclassing the class. `final public` also prevents the library itself 
 from doing this not only in future versions, but also in the current 
 version. This is very useful behavior that is not available if we adopt 
 your suggestion.
 
 >> Internal remains the same
 >> Fileprivate assimilates into private
 >>
 >> Make access control simple again!
 >
 > Agree.
 >
 > To me this discussion exemplifies the “square peg in a round hole” 
 > problem.
 > None of these (fileprivate & open) keywords add information to a source 
 > code. They do add noise however.
 >
 > The difference between fileprivate and private is only of importance to 
 > a group development effort. And then it is used for internal 
 > communication within that group, never to the outside world. In a way 
 > “private” tells other group members that they should ask the original 
 > developer why he choose private instead of fileprivate. (And more than 
 > often be told “just change it”)
 > This is something that would be better solved by comments imo.
 
 This is not true at all. I have found the distinction useful both in 
 personal projects and in a team environment.
 
 >
 > Open vs public is less obvious as there seems to be a use case for this. 
 > However in the end it only “forces” an API user to wrap the “public” 
 > interface so he can then use it again as “open”.
 > Hence it does not solve a design problem, it only leads to a cumbersome 
 > interface.
 
 Composition is often a better approach than inheritance. Allowing a 
 library to expose classes publicly is very valuable. It allows them the 
 ability to design classes that are not intended to be subclasses and have 
 that intent verified by the compiler. Supporting subclassing correctly is 
 difficult and not always appropriate.
 
 >
 >
 > Now, if we really want to add information to the source code, then we 
 > would do away with the restriction approach entirely and adopt an access 
 > list approach. I.e. it would 

Re: [swift-evolution] final + lazy + fileprivate modifiers

2017-02-14 Thread Slava Pestov via swift-evolution

> On Feb 12, 2017, at 8:19 AM, David Hart via swift-evolution 
>  wrote:
> 
> Lazy
> 
> This one is clearer: if Joe Groff's property behaviors proposal from last 
> year is brought forward again, lazy can be demoted from a language keyword to 
> a Standard Library property behavior. If Joe or anybody from the core team 
> sees this: do we have any luck of having this awesome feature we 
> discussed/designed/implemented in the Swift 4 timeframe?

Changing a property from ‘lazy’ to computed or a property behavior etc is going 
to be an ABI-compatible change, so deprecating this feature or replacing it 
with a standard library feature (with the appropriate syntax sugar to keep old 
code compiling) is certainly feasible after the ABI freeze.

Slava

> 
> Fileprivate 
> 
> I started the discussion early during the Swift 4 timeframe that I regret the 
> change in Swift 3 which introduced a scoped private keyword. For me, it's not 
> worth the increase in complexity in access modifiers. I was very happy with 
> the file-scope of Swift pre-3. When discussing that, Chris Latner mentioned 
> we'd have to wait for Phase 2 to re-discuss it and also show proof that 
> people mostly used 'fileprivate' and not the new 'private' modifier as proof 
> if we want the proposal to have any weight. Does anybody have a good idea for 
> compiling stats from GitHub on this subject? First of all, I've always found 
> the GitHub Search quite bad and don't know how much it can be trusted. 
> Secondly, because 'private' in Swift 2 and 3 have different meanings, a 
> simple textual search might get us wrong results if we don't find a way to 
> filter on Swift 3 code.
> 
> Thanks for hearing me out!
> 
> David.
> ___
> 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] Protocol requirement `where` clauses constraining associated types

2017-02-08 Thread Slava Pestov via swift-evolution

> On Feb 8, 2017, at 10:30 PM, Douglas Gregor  wrote:
> 
> 
>> On Feb 8, 2017, at 10:21 PM, Slava Pestov  wrote:
>> 
>> Hah, Doug and I were just discussing this.
>> 
>> In Swift 3.1, we generalized where clauses to allow them to add requirements 
>> on outer generic parameters. However we did not remove the diagnostic 
>> prohibiting a where clause from being attached to a non-generic method. In 
>> theory this can be made to work; the only slightly tricky thing is we will 
>> get a GenericParamList with zero parameters but non-zero requirements, which 
>> would require shuffling some things around to avoid assertions.
>> 
>> This would be a good starter project for someone who wanted to learn more 
>> about the generics system.
>> 
>> As for index(of:) and the specific details of the stdlib that are involved 
>> here, I have no idea — I’m just talking about the bogus diagnostic itself.
> 
> Well, I think Brent is talking about doing this on a protocol requirement, 
> which is more interesting because not all conforming types would satisfy the 
> requirement…

Since there would be no way to invoke the requirement on such a type, could we 
leave the entry blank in the witness table or emit a fatalError() thunk or 
something?

Slava

> 
>   - Doug
> 
>> 
>> Slava
>> 
>>> On Feb 8, 2017, at 9:57 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
>>> In an article on `Collection` today*, Ole Begemann points out that 
>>> `index(of:)`, along with other `Equatable`- and `Comparable`-constrained 
>>> `Collection` methods, cannot be overridden. Actually, it *can* be, but only 
>>> through a private mechanism—there's a `_customIndexOfEquatableElement(_:)` 
>>> method that's invisible in the generated interface. But that only proves 
>>> the need for a way to make methods like these overridable.
>>> 
>>> The problem is that the `index(of:)` method should only be offered when the 
>>> element is `Equatable`—otherwise it simply won't work. But there's no way 
>>> to specify this rule in current Swift. In theory, we could describe such a 
>>> requirement with something like this:
>>> 
>>> func index(of element: Iterator.Element) -> Index? where 
>>> Iterator.Element: Equatable
>>> 
>>> But this is not permitted—you get an error indicating that `where` clauses 
>>> are only allowed on generic methods. Adding a spurious generic parameter 
>>> allows this code to compile, but with a deprecation warning indicating that 
>>> this is deprecated. I don't know if it would actually behave correctly, 
>>> however.
>>> 
>>> Is this a feature we should add? Is this the way to add it? Would it have 
>>> non-additive ABI impact? (The private `index(of:)` override would certainly 
>>> go away, but that's why it's private, I suppose.) I don't seem to remember 
>>> seeing something like this in the generics manifesto, so I thought it was 
>>> worth bringing up.
>>> 
>>> 
>>> 
>>> * https://oleb.net/blog/2017/02/sorted-array/
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> ___
>>> 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] Protocol requirement `where` clauses constraining associated types

2017-02-08 Thread Slava Pestov via swift-evolution
Hah, Doug and I were just discussing this.

In Swift 3.1, we generalized where clauses to allow them to add requirements on 
outer generic parameters. However we did not remove the diagnostic prohibiting 
a where clause from being attached to a non-generic method. In theory this can 
be made to work; the only slightly tricky thing is we will get a 
GenericParamList with zero parameters but non-zero requirements, which would 
require shuffling some things around to avoid assertions.

This would be a good starter project for someone who wanted to learn more about 
the generics system.

As for index(of:) and the specific details of the stdlib that are involved 
here, I have no idea — I’m just talking about the bogus diagnostic itself.

Slava

> On Feb 8, 2017, at 9:57 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> In an article on `Collection` today*, Ole Begemann points out that 
> `index(of:)`, along with other `Equatable`- and `Comparable`-constrained 
> `Collection` methods, cannot be overridden. Actually, it *can* be, but only 
> through a private mechanism—there's a `_customIndexOfEquatableElement(_:)` 
> method that's invisible in the generated interface. But that only proves the 
> need for a way to make methods like these overridable.
> 
> The problem is that the `index(of:)` method should only be offered when the 
> element is `Equatable`—otherwise it simply won't work. But there's no way to 
> specify this rule in current Swift. In theory, we could describe such a 
> requirement with something like this:
> 
>   func index(of element: Iterator.Element) -> Index? where 
> Iterator.Element: Equatable
> 
> But this is not permitted—you get an error indicating that `where` clauses 
> are only allowed on generic methods. Adding a spurious generic parameter 
> allows this code to compile, but with a deprecation warning indicating that 
> this is deprecated. I don't know if it would actually behave correctly, 
> however.
> 
> Is this a feature we should add? Is this the way to add it? Would it have 
> non-additive ABI impact? (The private `index(of:)` override would certainly 
> go away, but that's why it's private, I suppose.) I don't seem to remember 
> seeing something like this in the generics manifesto, so I thought it was 
> worth bringing up.
> 
> 
> 
> * https://oleb.net/blog/2017/02/sorted-array/
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] Warning when omitting default case for imported enums

2017-02-09 Thread Slava Pestov via swift-evolution

> On Feb 8, 2017, at 1:34 AM, Tino Heth via swift-evolution 
>  wrote:
> 
> 
>> Allowing the omission of a default case in an exhaustive switch makes the 
>> addition of a new case to the enum a breaking change. 
> Depending on the context, even with a default the change might be breaking — 
> but without giving notice to the framework client!
> Additionally, it would feel very strange for me to have a default clause for 
> bool-like enums* or other examples where there can't be any additional cases.
> 
> When there are two types of enums, the proposal makes sense for the 
> "open"-ones; but I'm not sure if I like the concept of having two kinds of 
> enum.

Why not? Bool-like enums would be declared ‘closed’, and would not require a 
default case (but adding a new case would then break ABI).

For better or worse we need the ability to define enums that admit new cases 
without breaking ABI. Whether or not this is the default for all enums, or 
enabled with a special attribute can be designed later when we send out 
evolution proposals for resilience-related features.

Slava

> 
> - Tino
> 
> * tiny anecdote: I actually have seen the equivalent of this
> 
> func reallyExhaustive(input: Bool) {
>   if input == true {
>   print("true")
>   } else if input != true {
>   print ("not true")
>   } else {
>   print("just to be save")
>   }
> }
> 
> in the wild… but I don't remember the comment I wrote ;-)
> ___
> 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] Warning when omitting default case for imported enums

2017-02-10 Thread Slava Pestov via swift-evolution

> On Feb 10, 2017, at 8:55 AM, Tino Heth <2...@gmx.de> wrote:
> 
>>> I'm not sure if I like the concept of having two kinds of enum.
>> 
>> Why not? Bool-like enums would be declared ‘closed’, and would not require a 
>> default case (but adding a new case would then break ABI).
> 
> Well, enums are already (relative) complex, and with this addition, there 
> would be six different flavors.
> Imho it would be less bad if we could recycle existing modifiers, but with a 
> hypothetic "closed" access level added as well, I have strong doubts that the 
> feature carries its weight.

Closed would not be an access level, just an attribute orthogonal to the 
others. What do you mean by the six different flavors?

> 
>> For better or worse we need the ability to define enums that admit new cases 
>> without breaking ABI. Whether or not this is the default for all enums, or 
>> enabled with a special attribute can be designed later when we send out 
>> evolution proposals for resilience-related features.
> Intuitively, I thought this should not affect ABI… but no matter what 
> instability this is, I guess it could definitely crash an application that is 
> confronted with an unexpected case ;-)
> 
> Wouldn't it be possible to create an implicit default case for every 
> switch-statement?

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


Re: [swift-evolution] Class and Subclass Existentials (Round 2)

2017-02-14 Thread Slava Pestov via swift-evolution

> On Feb 12, 2017, at 12:32 PM, David Hart via swift-evolution 
>  wrote:
> 
> Hi Matthew,
> 
> Your arguments made sense to me. I modified the proposal to choose strategy 
> number 3: deprecating and removing class over several versions to favour 
> AnyObject. Mind having another proof read?
> 
> https://github.com/hartbit/swift-evolution/blob/subclass-existentials/proposals/-subclass-existentials.md
>  
> 
> 
> Anybody has counter arguments?
> 
> Class and Subtype existentials
> 
> Proposal: SE- 
> 
> Authors: David Hart , Austin Zheng 
> 
> Review Manager: TBD
> Status: TBD
>  
> Introduction
> 
> This proposal brings more expressive power to the type system by allowing 
> Swift to represent existentials of classes and subtypes which conform to 
> protocols.
> 
>  
> Motivation
> 
> Currently, the only existentials which can be represented in Swift are 
> conformances to a set of protocols, using the  composition syntax:
> 
> Protocol1 & Protocol2
> On the other hand, Objective-C is capable of expressing existentials of 
> classes and subclasses conforming to protocols with the following syntax:
> 
> id
> Base*
> We propose to provide similar expressive power to Swift, which will also 
> improve the bridging of those types from Objective-C.
> 
>  
> Proposed
>  solution
> 
> The proposal keeps the existing & syntax but allows the first element, and 
> only the first, to be either the AnyObjectkeyword or of class type. The 
> equivalent to the above Objective-C types would look like this:
> 
> AnyObject & Protocol1 & Protocol2
> Base & Protocol
> As in Objective-C, the first line is an existential of classes which conform 
> to Protocol1 and Protocol2, and the second line is an existential of subtypes 
> of Base which conform to Protocol.
> 
> Here are the new proposed rules for what is valid in a existential 
> conjunction syntax:
> 
>  
> 1.
>  The first element in the protocol composition syntax can be the AnyObject 
> keyword to enforce a class constraint:
> 
> protocol P {}
> struct S : P {}
> class C : P {}
> let t: P & AnyObject // Compiler error: AnyObject requirement must be in 
> first position
> let u: AnyObject & P = S() // Compiler error: S is not of class type
> let v: AnyObject & P = C() // Compiles successfully
>  
> 2.
>  The first element in the protocol composition syntax can be a class type to 
> enforce the existential to be a subtype of the class:
> 
> protocol P {}
> struct S {}
> class C {}
> class D : P {}
> class E : C, P {}
> let t: P & C // Compiler error: subclass constraint must be in first position
> let u: S & P // Compiler error: S is not of class type
> let v: C & P = D() // Compiler error: D is not a subtype of C
> let w: C & P = E() // Compiles successfully
>  
> 3.
>  When a protocol composition type contains a typealias, the validity of the 
> type is determined using the following steps:
> 
> Expand the typealias
> Normalize the type by removing duplicate constraints and replacing less 
> specific constraints by more specific constraints (a class constraint is less 
> specific than a class type constraint, which is less specific than a 
> constraint of a subclass of that class).
> Check that the type does not contain two class-type constraints

You could generalize this and instead say that if the type contains two 
class-type constraints, the resulting existential type is the common base class 
of the two classes, or AnyObject if they do not share a common base class.

Also, I’d like to see some discussion about class-constrained existentials 
appearing in the inheritance clause of a protocol. IMHO, we should ban this:

typealias MyType = SomeClass & SomeProtocol

protocol SomeOtherProtocol : MyType {}

Slava

> class C {}
> class D : C {}
> class E {}
> protocol P1 {}
> protocol P2 {}
> typealias TA1 = AnyObject 

Re: [swift-evolution] [Pitch] consistent public access modifiers

2017-02-12 Thread Slava Pestov via swift-evolution
Also, note that there will be at least one other similar annotation, but for 
structs — the evolution document calls it @fixedContents. We want a way to 
declare that the set of stored properties in a struct will never change, 
allowing clients to make assumptions about its layout. Unlike @closed enums, 
@fixedContents structs mostly behave the same. The one important difference is 
that it will be possible to define designated initializers of @fixedContents 
structs inside extensions from another module.

Slava

> On Feb 12, 2017, at 8:49 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On Feb 12, 2017, at 10:39 AM, Nevin Brackett-Rozinsky via swift-evolution 
>> > wrote:
>> 
>> Alternative: leave “public enum” as it is now, and spell the resilient 
>> version “@resilient enum”
> 
> The problem with this approach is that the “default” is the stricter contract 
> and library authors have to remember to add the annotation to opt-out of that 
> stricter contract.  The problems created by the stricter contract will only 
> appear later when the author realizes they need to add new cases and now it’s 
> a breaking change.  
> 
> Responsible library authors should always make an intentional choice, but 
> sometimes even the best of us make mistakes.  If a library author makes this 
> mistake it is likely that it won’t be noticed until it is too late.  
> Requiring the library author to make a choice between mutually exclusive 
> options rather than a choice to add or omit an annotation reduces the chance 
> of the library author making this error.  
> 
> This is the rationale that led to us adding `open` rather than adding 
> something like an `@closed` annotation for classes.  The desire to avoid 
> growing lots of annotations in the language was also an important 
> consideration that I believe applies here.
> 
>> 
>> Nevin
>> 
>> 
>> On Sunday, February 12, 2017, Matthew Johnson via swift-evolution 
>> > wrote:
>> 
>>> On Feb 12, 2017, at 10:24 AM, David Hart > wrote:
>>> 
>>> 
>>> On 12 Feb 2017, at 16:38, Matthew Johnson > wrote:
>>> 
 
> On Feb 12, 2017, at 12:50 AM, David Hart > wrote:
> 
> Hi Matthew,
> 
> I've read your proposal ideas and most of the discussions on the thread, 
> and I'd like to provide some personal feedback.
> 
> Swift already has a complicated "access modifier" story so I think we 
> really want a good reason to introduce a new one. And the problem I see 
> is that `closed` has much less semantic weight than the other modifiers.
 
 How so?  I’m not sure if I catch your meaning here.  It feels to me like 
 it has the same semantic weight as `open`: prohibiting future versions of 
 a module from adding cases / subclasses / conformances is roughly the 
 inverse of lifting the restriction that clients cannot add those things.  
 Therefore it has roughly the same degree of additional meaning over 
 `public` as `open` does.
>>> 
>>> The difference I see is precisely that 'public' and 'open' modifiers limit 
>>> what the client of a module can do while closed limits what future versions 
>>> of a module can do. Feels quite different to me.
>> 
>> This is a reasonable point and is perhaps the strongest argument made 
>> against my proposal thus far.  However, I think we have to consider my 
>> proposal relative to the alternatives.  
>> 
>> The only alternative I am aware of is making `public enum` the resilient 
>> variety and using `@closed public enum` for the closed variety.  This means 
>> that `public` will have at least two different semantics (three if we don’t 
>> reconcile classes and protocols).  It also means that the resilient variety 
>> is effectively the default.  I am really happy that we decide not to have a 
>> default between `open` and `public` and think the best choice is that we 
>> don’t have one here either.  The fact that we have a way to do this while 
>> solving the inconsistent semantics of `public` feels like a net win to me.
>> 
>>> 
> 
> First of all, the Library Evolution document you linked says toward at 
> the top that "this document is primarily concerned with binary 
> compatibility, i.e. what changes can safely be made to a library between 
> releases that will not break memory-safety or type-safety, or cause 
> clients to fail to run at all." It seems to me that the @closed 
> introduced in that document is much more about library resilience than 
> about only closing down the addition of new cases: that's why it also 
> talks about reordering and all other changes that can change the memory 
> layout.
> 
> Swift 3 having introduced both fileprivate and open has complexified the 
> access level story for 

Re: [swift-evolution] Does protocol support add to an object's size?

2017-02-15 Thread Slava Pestov via swift-evolution
Values of concrete type always have the same size regardless of what protocols 
the type conforms to.

Slava
 
> On Feb 15, 2017, at 9:51 AM, Daryle Walker via swift-evolution 
>  wrote:
> 
> I don't know how protocol support works. I asking because I want to maintain 
> the stride of an array being the total count times the stride of the element, 
> which would complicate nominal arrays if adding protocols to one breaks that. 
> 
> Sent from my iPhone
> ___
> 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] final + lazy + fileprivate modifiers

2017-02-17 Thread Slava Pestov via swift-evolution

> On Feb 17, 2017, at 12:09 AM, Charlie Monroe via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> True, what I meant was a wider feedback - let's face it, there are many more 
> Swift developers now than 2 years ago.
> 
> My objection is not to the documentation itself, but to the fact that I'm 
> unnecessarily exposing an internal implementation detail to the rest of the 
> module. Being able to hide it from the rest IMHO leads to better 
> though-through API that is indeed meant to be exposed; whereas exposing 
> internal details leads to allowing various quick hacks instead. We know these 
> quick hacks very well from the ObjC world by accessing private parts of the 
> object via duck typing or setting values via KVO.
> 
> At least this is my experience with which the less implementation details are 
> exposed to the outer world, the better.

I think the fundamental disagreement we’re seeing in this thread is the meaning 
of “outer world”; to some, it means “users of your module”. To others, it also 
means “other developers on my team who are working on other files in the 
module”.

Personally I feel enforced encapsulation of implementation detail to the latter 
group is less important than the former, and can be handled by convention. 
Whereas other users of your module definitely benefit from access control and 
being able to consume a clearly-defined interface.

Slava

> 
>> On Feb 17, 2017, at 8:54 AM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> That blog post starts out right away to say that it's a response to 
>> community feedback. Moreover, the scenario you describe was just as possible 
>> in 2014 as it is now. Finally, then as now, it's unclear why you consider 
>> documentation to be "not pretty." After all, your reader would need to 
>> consult the documentation before using a variable anyway.
>> On Fri, Feb 17, 2017 at 01:04 Charlie Monroe via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> I'm aware of this, but that's fairly a long time ago - before Swift was open 
>> source and had community feedback and before Swift was used widely among 
>> developers.
>> 
>> To me, real-world use of the language has shown some flaws of missing a 
>> protected access control, mainly having to decide between having a variable 
>> internal or cramming all of the class extension into one file, making it a 
>> 3KLOC mess. Either solution is not pretty - now I have it split among 
>> several files with an internal variable commented as "Do not use, for 
>> private use of this class only."
>> 
>>> On Feb 17, 2017, at 7:47 AM, Jose Cheyo Jimenez <ch...@masters3d.com 
>>> <mailto:ch...@masters3d.com>> wrote:
>>> 
>>> https://developer.apple.com/swift/blog/?id=11 
>>> <https://developer.apple.com/swift/blog/?id=11>
>>> 
>>> 
>>> 
>>> On Feb 16, 2017, at 10:05 PM, Charlie Monroe via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> How about removing fileprivate, getting Swift 2 meaning of private (as 
>>>> most people here now suggest) and add additional @protected annotation for 
>>>> those who want a more fine-grained solution:
>>>> 
>>>> @protected private - members accessable only from the 
>>>> class/struct/enum/... and their extensions within the file
>>>> 
>>>> @protected internal - again, but you can access it even from extensions 
>>>> and subclasses outside of the file within the entire module.
>>>> 
>>>> @protected public/open - the same as above, but outside the modules.
>>>> 
>>>> To me, this way most people here will be happy:
>>>> 
>>>> - those wishing the access control gets simplified - it in fact does, you 
>>>> don't need to use @protected, if you don't want to/need to.
>>>> - those who need a fine-grained solution, here it is.
>>>> 
>>>> 
>>>> 
>>>>> On Feb 17, 2017, at 3:49 AM, Matthew Johnson via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>> Sent from my iPad
>>>>> 
>>>>>> On Feb 16, 2017, at 8:36 PM, David Sweeris via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>

Re: [swift-evolution] final + lazy + fileprivate modifiers

2017-02-16 Thread Slava Pestov via swift-evolution
While we’re bikeshedding, I’m going to add my two cents. Hold on to your hat 
because this might be controversial here.

I think both ‘private’ and ‘fileprivate’ are unnecessary complications that 
only serve to clutter the language.

It would make a lot more sense to just have internal and public only. No 
private, no fileprivate, no lineprivate, no protected. It’s all silly.

Slava

> On Feb 15, 2017, at 7:40 AM, T.J. Usiyan via swift-evolution 
>  wrote:
> 
> "Either keep it or drop it, but don't keep fiddling with it." sums up my 
> position well.
> 
> On Wed, Feb 15, 2017 at 7:00 AM, Brent Royal-Gordon via swift-evolution 
> > wrote:
> > On Feb 14, 2017, at 9:31 PM, Chris Lattner via swift-evolution 
> > > wrote:
> >
> > Keeping with the spirit of Swift and staying consistent with its design, I 
> > see two plausible meanings for private:
> >
> > Private could mean either:
> > 1) private to the file (Swift 2 semantics)
> > 2) accessible only to the current type/scope and to extensions to that type 
> > that are in the current file.
> >
> > I don’t think we’ve ever evaluated and debated approach #2 systematically.
> 
> For what it's worth:
> 
> I was opposed to SE-0025, but since I lost, I have tried to use `private` 
> wherever it made sense, rather than fighting with the language.
> 
> Sometimes, the change of keyword makes no difference. Other times, it's a 
> hassle, because I have to switch between `private` and `fileprivate` as I 
> redesign things, with little perceived benefit. I'd say the split between 
> these is about 50/50.
> 
> On a few occasions, I *have* genuinely appreciated the SE-0025 version of 
> `private`. These involved cases where I wanted to ensure that instance 
> variables were only manipulated in certain ways, using interfaces I had 
> specifically designed to handle them correctly. For instance, I might have 
> two parallel arrays, and I wanted to make sure that I only added or removed 
> elements from both arrays at once. I could do this with `fileprivate` by 
> splitting the type into two files, but it was more convenient to do it in one.
> 
> In these cases, switching to #2 would *completely* defeat the purpose of 
> using `private`, because the extensions would be able to directly manipulate 
> the private instance variables. I would no longer gain any benefit at all 
> from `private`. All of my uses would either fall into "makes no difference" 
> or "it's a hassle".
> 
> I do not support the idea of changing `private` to mean #2. Doing so would 
> eliminate the few decent use cases I've found for `private`. Either keep it 
> or drop it, but don't keep fiddling with it.
> 
> --
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] Will existentials ever conform to their protocols?

2017-01-18 Thread Slava Pestov via swift-evolution
Yes, there’s already logic to detect and diagnose this case in fact (@objc 
protocols are self-conforming, except when they contain static members or 
initializers).

Slava

> On Jan 18, 2017, at 12:10 AM, Anton Zhilin via swift-evolution 
>  wrote:
> 
> There is also a caveat with static members:
> 
> protocol P {
> static func foo()
> }
> 
> struct S : P {
> static func foo() { }
> }
> 
> func bar(x: T) {
> T.foo()
> }
> 
> let p = S() as P
> bar(p)  // P.foo() does not exist
> ___
> 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] Nested types in protocols (and nesting protocols in types)

2017-01-18 Thread Slava Pestov via swift-evolution
I left some review comments here:

https://github.com/apple/swift-evolution/commit/ff654e4

Slava

> On Jan 18, 2017, at 12:17 AM, Karl Wagner <razie...@gmail.com> wrote:
> 
> 
>> On 18 Jan 2017, at 01:07, Douglas Gregor <dgre...@apple.com 
>> <mailto:dgre...@apple.com>> wrote:
>> 
>> 
>>> On Nov 5, 2016, at 2:44 AM, Karl via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> 
>>>> On 2 Nov 2016, at 20:54, Slava Pestov <spes...@apple.com 
>>>> <mailto:spes...@apple.com>> wrote:
>>>> 
>>>>> 
>>>>> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <cantr...@pobox.com 
>>>>> <mailto:cantr...@pobox.com>> wrote:
>>>>> 
>>>>> 
>>>>>> On Oct 24, 2016, at 4:43 PM, Slava Pestov <spes...@apple.com 
>>>>>> <mailto:spes...@apple.com>> wrote:
>>>>>> 
>>>>>> 
>>>>>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <cantr...@pobox.com 
>>>>>>> <mailto:cantr...@pobox.com>> wrote:
>>>>>>> 
>>>>>>> 
>>>>>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>>>> 
>>>>>>>> However protocols nested inside types and types nested inside 
>>>>>>>> protocols is still not supported, because protocols introduce a 
>>>>>>>> separate series of issues involving associated types and the ’Self’ 
>>>>>>>> type.
>>>>>>>> 
>>>>>>>> The hard part of getting nested generics right is what to do if a 
>>>>>>>> nested type ‘captures’ generic parameters of the outer type. For 
>>>>>>>> non-protocol types, the behavior here is pretty straightforward.
>>>>>>>> 
>>>>>>>> If we allow protocols to be nested inside other types, we have to 
>>>>>>>> decide what to do if the protocol ‘closes over’ generic parameters of 
>>>>>>>> the outer type. For example,
>>>>>>>> 
>>>>>>>> struct A {
>>>>>>>> protocol P {
>>>>>>>> func requirement() -> T
>>>>>>>> }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> Presumably A.P and A.P are distinct types, and A.P has a 
>>>>>>>> hidden associated type corresponding to the type parameter ’T’?
>>>>>>>> 
>>>>>>>> The other case is problematic too — the nested type might refer to an 
>>>>>>>> associated type of the outer protocol:
>>>>>>>> 
>>>>>>>> protocol P {
>>>>>>>> associatedtype A
>>>>>>>> 
>>>>>>>> struct T {
>>>>>>>> var value: A
>>>>>>>> }
>>>>>>>> }
>>>>>>>> 
>>>>>>>> Now writing P.T does not make sense, for the same reason that we 
>>>>>>>> cannot form an existential of type P.A. We could prohibit references 
>>>>>>>> to outer associated types of this form, or we could figure out some 
>>>>>>>> way to give it a meaning. If C is a concrete type conforming to P, 
>>>>>>>> then certainly C.T makes sense, for instance. Internally, the nested 
>>>>>>>> type A.T could have a hidden ‘Self’ generic type parameter, so that 
>>>>>>>> writing C.T is really the same as P.T.
>>>>>>>> 
>>>>>>>> Protocols nested inside protocols also have the same issue.
>>>>>>> 
>>>>>>> FWIW, in almost all the situations where I’ve wanted to nest types 
>>>>>>> inside protocols and generic types, it’s only as a namespacing 
>>>>>>> convenience. Most often, it’s an enum type that’s used only by a single 
>>>>>>> method, and having it at the top of the module namespace adds clutter.
>>>>>>> 
>>>>>>> Here’s a real life example pared down. I wish I could do this:
>>>>>>> 

Re: [swift-evolution] Will existentials ever conform to their protocols?

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

> On Jan 17, 2017, at 9:33 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> On Jan 17, 2017, at 22:30, Braeden Profile via swift-evolution 
> > wrote:
> 
>> Hello Swift Community!
>> 
>> I know that I’ve seen this mentioned before, but what with Enhanced 
>> Existentials being brought up, I think this is worth mentioning now.  What 
>> is the plan regarding letting existentials conform to their protocols?  
>> Currently, in Swift 3, it is impossible to write code like this:
>> protocol Updatable
>>  { func update() }
>> 
>> struct UpdatePool
>>  { /* ... */ }
>> 
>> let heterogenousPool = UpdatePool()
>> Error on the last line:  “Using ‘Updatable’ as a concrete type conforming to 
>> protocol ‘Updatable’ is not supported.”
>> 
>> 
>> Although my most common use case of this behavior has actually been solved 
>> (using ‘AnyObject’ as a concrete type conforming to ‘AnyObject’), I wonder 
>> why this can’t be extended to any protocol existential (a field which is 
>> about to explode, if we succeed in Enhancing them).
>> 
>> What do you guys think?
> 
> +1, but I think there's a compiler limitation preventing it at the moment.

See my recent post: 
https://www.mail-archive.com/swift-users@swift.org/msg03427.html

Slava


> 
> - Dave Sweeris 
> ___
> 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] Swift Evolution Status Page Now Available

2017-01-18 Thread Slava Pestov via swift-evolution
This looks great, thanks!

SE-0080 was recently implemented by a contributor and will be available in 
Swift 4:

https://github.com/apple/swift/pull/4314

Slava

> On Jan 18, 2017, at 2:04 PM, Kyle Murray via swift-evolution 
>  wrote:
> 
> Hi everyone,
> 
> We've just launched a new status page 
>  for keeping track of Swift 
> Evolution proposals. See the announcement in a post on the swift.org blog 
> . 
> 
> A few of the benefits to the new page are:
> Search for proposals by criteria such as the proposal's author or Swift 
> version number.
> See which proposals have implementations in progress via the associated JIRA 
> issues.
> The status of a proposal is read directly from its Markdown source. The 
> separate XML file is no longer needed.
> 
> The status page displays progress and information about proposals as they go 
> through the evolution process. As always, please follow the standard proposal 
> template 
>  to 
> keep to process running efficiently. Formatting your proposal correctly also 
> ensures that it's picked up and displayed correctly on the status page. 
> 
> If you're interested in contributing to the status page's implementation, see 
> the steps for doing so in CONTRIBUTING.md 
> . 
> 
> We're looking forward to your feedback!
> 
> Thanks,
> Kyle
> ___
> 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] Availability checking of libraries (weak linking?)

2017-01-18 Thread Slava Pestov via swift-evolution
Extending availability to support library versioning would be a great proposal.

You should also take a look at the library evolution proposal, where this 
functionality will be required to implement the resilience model: 
https://github.com/apple/swift/blob/master/docs/LibraryEvolution.rst

Slava

> On Jan 18, 2017, at 4:24 PM, Swizzlr via swift-evolution 
>  wrote:
> 
> Say I have an awesome type, and I provide some extensions that makes it work 
> really well with a few other packages.
> 
> I don't want to force those packages on my users, but if they have them, I 
> want to extend them with my awesome type/function/whatever convenience.
> 
> What can be done in code and package manager to weakly link (not literally, I 
> just mean have that behaviour) my awesome type with all these other libraries?
> 
> This is a prelude to a pitch, if there isn't a decent alternative.
> 
> Tom
> 
> Sent from my iPhone
> ___
> 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] Swift Evolution Status Page Now Available

2017-01-18 Thread Slava Pestov via swift-evolution
Actually it’s available in swift-3.1-branch also.

Kyle, do you mind updating this, or is there a way we can submit updates?

Slava

> On Jan 18, 2017, at 2:06 PM, Slava Pestov via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> This looks great, thanks!
> 
> SE-0080 was recently implemented by a contributor and will be available in 
> Swift 4:
> 
> https://github.com/apple/swift/pull/4314 
> <https://github.com/apple/swift/pull/4314>
> 
> Slava
> 
>> On Jan 18, 2017, at 2:04 PM, Kyle Murray via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Hi everyone,
>> 
>> We've just launched a new status page 
>> <https://apple.github.io/swift-evolution/> for keeping track of Swift 
>> Evolution proposals. See the announcement in a post on the swift.org blog 
>> <https://swift.org/blog/swift-evolution-status-page/>. 
>> 
>> A few of the benefits to the new page are:
>> Search for proposals by criteria such as the proposal's author or Swift 
>> version number.
>> See which proposals have implementations in progress via the associated JIRA 
>> issues.
>> The status of a proposal is read directly from its Markdown source. The 
>> separate XML file is no longer needed.
>> 
>> The status page displays progress and information about proposals as they go 
>> through the evolution process. As always, please follow the standard 
>> proposal template 
>> <https://github.com/apple/swift-evolution/blob/master/-template.md> to 
>> keep to process running efficiently. Formatting your proposal correctly also 
>> ensures that it's picked up and displayed correctly on the status page. 
>> 
>> If you're interested in contributing to the status page's implementation, 
>> see the steps for doing so in CONTRIBUTING.md 
>> <https://github.com/apple/swift-evolution/blob/master/CONTRIBUTING.md>. 
>> 
>> We're looking forward to your feedback!
>> 
>> Thanks,
>> Kyle
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto: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] [Review] SE-0148 Generic Subscripts

2017-01-19 Thread Slava Pestov via swift-evolution
Can we also add mention that default arguments on subscripts should work as 
well? This will force whoever implements this to do it properly and rip out the 
old RValue-based argument tuple emission that’s only used for subscripts in 
favor the argument emission logic.

Slava

> On Jan 19, 2017, at 1:39 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of SE-0148 “Generic Subscripts" begins now and runs through 
> January 24, 2017. The proposal is available here:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0148-generic-subscripts.md
>  
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> Proposal link:
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0148-generic-subscripts.md
>  
> 
> Reply text
> 
> Other replies
>  What 
> goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
> What is your evaluation of the proposal?
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
> Does this proposal fit well with the feel and direction of Swift?
> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
> More information about the Swift evolution process is available at
> 
> https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> Thank you,
> 
> -Doug
> 
> Review Manager
> 
> ___
> 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] Closures from methods with default args

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

> On Jan 19, 2017, at 9:07 PM, David Sweeris via swift-evolution 
>  wrote:

> It causes other issues, too. For instance, if we have
> protocol Initable { init() }
> And
> struct Foo { init(_ x: Int = 0) {} }
> We're left in an odd situation where `Foo`  can't meaningfully conform to 
> `Initable` because while "init(_: Int = 0)" is not the same as "init()", if 
> you add a "init()" to `Foo`
> you'll get an ambiguous somethingerather error because there's no mechanism 
> for the compiler to know whether you want the actual "0 argument" function or 
> the "1 argument with 1 default value" function.
> 
> Aside from re-architecting the default argument system (which I'm not even 
> sure is possible, let alone a good idea), I think I see couple ways forward 
> for the protocol conformance issue. Both have downsides, though.
> 
> 1) Require any potentially conflicting protocol functions to be in an 
> extension so the compiler knows what's going on, have "Foo()" call the one 
> defined in the type, and use "(Foo as Initable)()" for the protocol version 
> defined in an extension. This could get real confusing real fast if people 
> don't realize there's two functions with, as far as they can tell, the same 
> signature.
> 
> 2) Add default argument support to protocols. The syntax that makes sense to 
> me would be something like
> protocol Bar {
> func baz(_: Int = _)
> }
> On the downside, I suspect this would necessarily add a phantom "Self or 
> associated type requirement" so that the compiler could have a way to get at 
> each implementation's default value. It's not ideal... You'd get an error 
> kinda out of the blue if you tried to use the function non-generically, but 
> at least you couldn't have a function change out from under you.

I think in this specific example, the best solution is to allow init(_ x: Int = 
0) to witness the init() requirement, and have the compiler emit the necessary 
glue in-between so that a call to the init() requirement calls init(_) with the 
appropriate default value. This will address the ‘ambiguous reference’ issue, 
and should not require too much work to implement. I am also inclined to 
believe this is (mostly) a source-compatible change. It also fits in with the 
current default argument model, but Doug Gregor can correct me if I’m wrong.

If anyone is interested, the code for matching protocol requirements to 
witnesses is in lib/Sema/TypeCheckProtocol.cpp, matchWitness() and surrounding 
functions, and the code for emitting a protocol witness thunk (where you would 
actually apply the default arguments) is in lib/SILGen/SILGenPoly.cpp, 
emitProtocolWitness(). It would be a good not-quite-starter-project ;-)

Slava

> 
> - Dave Sweeris 
> ___
> 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] Assigning to 'self' in protocol extensions

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

> On Jan 19, 2017, at 10:52 PM, rintaro ishizaki via swift-evolution 
>  wrote:
> 
> From the perspective of the caller, I think, this behavior is 
> counterintuitive because we use "reference types" with an expectation: the 
> referencing address would never be changed unless we explicitly replace the 
> object by re-assigning to the variable in call sites, e.g.,
> 
> 

Well, there’s no real difficulty here, other than potential user confusion. The 
‘self’ parameter for a mutating method is passed inout, so this behaves as if 
you called a global function with an inout argument. The difference is of 
course when you pass a non-self inout argument, the compiler requires you to 
use the explicit & syntax at the call site.

Is your proposal to ban calls to such mutating methods on a type that is known 
to be a reference type at compile time altogether? This will create an 
inconsistency between code that operates on concrete types and code that 
operates on generic parameters (in the latter case the compiler of course has 
no way to statically guarantee that the value is not a reference type).

The last time this quirk came up in internal discussions, the thought some of 
us had was that it might be worthwhile to prohibit classes from conforming to 
protocols with mutating requirements altogether. If you think about it, this 
makes some amount of sense — it seems like it would be quite hard to write code 
that can operate on both mutable values and mutable references generically, 
since the latter do not have value semantics:

var x = y
x.mutatingProtocolRequirement()
// did y change too?

However the discussion sort of fizzled out.

Perhaps we can resurrect it as a proposal, but the bar is pretty high for 
removing features at this point, since there’s no actual type soundness issue, 
just possible confusion.

> var ref: Foo = Foo()
> ref = Foo()
>  
> Default
>  implementation for initializers
> 
> Similar to methods, initializers also have this issue:
> 
In the specific case of initializers, my opinion here is the opposite in fact — 
I think assigning to ‘self’ should be permitted in all convenience 
initializers, even initializers defined directly classes, without the protocol 
extension trick. Also, we should lower this more efficiently than we do today, 
without creating a self ‘carcass’ that is allocated and immediately freed, to 
be replaced by the ‘real’ self.

We already have something like this in fact, it’s called ‘factory 
initializers', but it’s not directly exposed through the language. It is 
possible to import a static method or C function as a convenience initializer 
on a type. The Dispatch overlay uses this for example — DispatchQueue.init 
actually calls dispatch_queue_create(), which returns a new instance of the 
type, and not [[OS_dispatch_queue alloc] init] as you would expect if this was 
a vanilla Objective-C class. The code that gets generated here is similar to 
the protocol extension initializer example you show that assigns to ‘self’.

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


Re: [swift-evolution] Calling a Specific Implementation

2016-08-18 Thread Slava Pestov via swift-evolution

> On Aug 18, 2016, at 8:21 PM, Ben Rimmington via swift-evolution 
>  wrote:
> 
> 
>> On 18 Aug 2016, at 16:32, John McCall  wrote:
>> 
>> Unapplied method references still dispatch down.  It's a pretty simple 
>> experiment to run for yourself.
> 
> When I tried calling a specific superclass implementation, there was a stack 
> overflow due to the infinite recursion.

This is because calling Once.value() with an instance of Twice still dispatches 
to Twice::value().

> 
>   class Once {
>   func value() -> Int {
>   return 1
>   }
>   }
> 
>   class Twice: Once {
>   override func value() -> Int {
>   return 2
>   }
>   }
> 
>   class Thrice: Twice {
>   override func value() -> Int {
>   return 3
> 
>   // EXC_BAD_ACCESS:
>   // return Once.value(self)()
>   }
>   }
> 
>   let once = Once()
>   once.value()//-> 1
>   Once.value(once)()  //-> 1
> 
>   let twice = Twice()
>   twice.value()   //-> 2
>   Once.value(twice)() //-> 2
>   Twice.value(twice)()//-> 2
> 
>   let thrice = Thrice()
>   thrice.value()  //-> 3
>   Once.value(thrice)()//-> 3
>   Twice.value(thrice)()   //-> 3
>   Thrice.value(thrice)()  //-> 3
> 
> -- Ben
> 
> ___
> 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: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 16, 2016, at 8:52 PM, Charles Srstka  wrote:
> 
>> On Aug 16, 2016, at 8:51 PM, Slava Pestov > > wrote:
>> 
>> Here is why we must have that requirement. Consider the following code:
>> 
>> protocol P {
>>   init()
>> }
>> 
>> struct A : P {
>>   init() {}
>> }
>> 
>> struct B : P {
>>   init() {}
>> }
>> 
>> func makeIt() -> T {
>>   return T()
>> }
>> 
>> I can use this function as follows:
>> 
>> let a: A = makeIt() // Creates a new ‘A'
>> let a: B = makeIt() // Creates a new ‘B’
>> 
>> Now suppose we allow P to self-conform. Then the following becomes valid:
>> 
>> let p: P = makeIt()
>> 
>> What exactly would makeIt() do in this case? There’s no concrete type passed 
>> in, or any way of getting one, so there’s nothing to construct. The same 
>> issue would come up with static methods here.
> 
> Argh, that’s particularly frustrating since in something like ‘func foo P>(t: T)’ or ‘func foo(s: S) where S.IteratorElement: P’, 
> you’re only ever getting instances anyway since the parameter is in the 
> input, so calling initializers or static functions isn’t something you can 
> even do (unless you call .dynamicType, at which point you *do* have a 
> concrete type at runtime thanks to the dynamic check).

Well, if you have ‘func foo(t: T)’, then you can write 
T.someStaticMember() to call static members — it’s true you also have an 
instance ’t’, but you can also work directly with the type. But I suspect this 
is not what you meant, because:

> 
> I wish there were a way to have partial conformance in cases like these. Like 
> how this causes what’s probably Swift’s most confusing compiler error 
> (certainly one of its most asked about):
> 
> protocol P: Equatable {
> static func ==(l: Self, r: Self) -> Bool
> 
> func foo()
> }
> 
> struct S: P {
> static func ==(l: S, r: S) -> Bool {
> return true
> }
> 
> func foo() {
> print("foo")
> }
> }
> 
> let s = S()
> let p = s as P // error: Protocol ‘P’ can only be used as a generic 
> constraint because it has Self or associated type requirements

Yep :) So the property of ‘can be used as an existential type’ is actually a 
bit different from ‘protocol conforms to itself’. The rules here are:

- Self must not appear in contravariant position
- Protocol has no associated types

Note that static members and initializers are OK, and you can call them via 
‘p.dynamicType.foo()’ where p : P.

> 
> It would make using protocols so much less teeth-grinding if the compiler 
> *did* allow you to type the variable as P, but then would just throw an error 
> if you tried to call one of the “problem” methods (in this case, using the 
> ‘==' operator would be an error, but calling ‘foo’ would be fine). If this 
> were possible, the conformance for a variable typed P would just not pick up 
> “illegal” things like initializers, and would also leave out conformance for 
> things like 'makeIt()' above which return the generic parameter in the 
> output, rather than the input, necessitating a concrete type. I’m probably 
> dreaming, I know.

In the type checker, this more precise, per-member check is already 
implemented, interestingly enough. It comes up with protocol extensions. 
Imagine you have a protocol ‘P’ that can be used as an existential, but an 
extension of P adds a problematic member:

protocol P {
  func f() -> Int
}

extension P {
  func ff(other: Self) -> Int { return f() + s.f()) }
}

Here, you don’t want to entirely ban the type ‘P’, because the extension might 
come from another module, and it shouldn’t just break everyone’s code. So the 
solution is that you can use ‘P’ as an existential, but if you try to reference 
‘p.ff’ where p : P, you get a diagnostic, because that particular member is 
unavailable.

In fact, I think the separate restriction that rules out usage of the overall 
type when one of the protocol’s requirements is problematic, is mostly 
artificial, in that it could just be disabled and you’d be able to pass around 
‘Equatable’ values, etc, because the lower layers don’t care (I think).

I do remember it was explained to me at one point that this is how it was in 
the early days of Swift, but it made code completion and diagnostics confusing, 
because with some protocols (like Sequence) most members became inaccessible.

A better approach is to implement more general existential types which expose 
ways of working with their associated types, rather than just banning certain 
members from being used altogether. This is described in Doug's ‘completing 
generics’ document, and again, it is quite a large project :)

> 
> Actually, what I wish is that Swift had an equivalent of the 'id ’ type in 
> Objective-C. That notation always stood for an instance of something that 
> conformed to P, rather than "maybe P itself, and maybe something that 
> conforms to it”. If we could do that, we could just pass sequences 

Re: [swift-evolution] PITCH: New :== operator for generic constraints

2016-08-16 Thread Slava Pestov via swift-evolution

> On Aug 16, 2016, at 10:16 PM, Charles Srstka  wrote:
> 
>> On Aug 16, 2016, at 11:42 PM, Slava Pestov > > wrote:
>>> 
>>> Argh, that’s particularly frustrating since in something like ‘func foo>> P>(t: T)’ or ‘func foo(s: S) where S.IteratorElement: P’, 
>>> you’re only ever getting instances anyway since the parameter is in the 
>>> input, so calling initializers or static functions isn’t something you can 
>>> even do (unless you call .dynamicType, at which point you *do* have a 
>>> concrete type at runtime thanks to the dynamic check).
>> 
>> Well, if you have ‘func foo(t: T)’, then you can write 
>> T.someStaticMember() to call static members — it’s true you also have an 
>> instance ’t’, but you can also work directly with the type. But I suspect 
>> this is not what you meant, because:
> 
> Agh, you’re right, I’d forgotten about that. It’s days like this that I miss 
> Objective-C’s “It just works” dynamism. ;-)

Objective-C doesn’t have an equivalent of associated types or contravariant 
Self, but I understand your frustration, because Sequence and Equatable are 
pervasive in Swift.

> The other trouble is that it’s not just confusing; it can very easily get in 
> the way of your work even if you know exactly what’s going on, necessitating 
> kludges like AnyHashable just to do things like have a dictionary that can 
> take more than one key type (an example that’s particularly irritating since 
> the only method you care about, hashValue, is just a plain old Int that 
> doesn’t care about the Self requirement at all). I know that a while ago I 
> ended up using my own Equatable substitute with an ObjC-style isEqual() 
> method on some types, just because actually implementing Equatable was 
> throwing a huge spanner into the rest of the design.

Yeah, AnyHashable is basically a hand-coded existential type. It would also be 
possible to do something similar for Equatable, where an AnyEquatable type 
could return false for two values with differing concrete types, removing the 
need for an == with contra-variant Self parameters.

Generalized existentials eliminate the restriction and thus the hacks. On the 
other hand, they add yet more complexity to the language, so designing them 
correctly involves difficult tradeoffs.

> Well, the idea was to create an easier-to-implement alternative to 
> self-conforming protocols, which could be done if :== were expanded to one 
> function that uses ==, and another with the same body that uses :, because I 
> was under the impression that the compiler team did not want to implement 
> self-conforming protocols.

I think the underlying machinery would be the same. We only want to compile the 
body of a generic function body, without any kind of cloning like in C++ 
templates, producing a general uninstantiated runtime form. So :== T 
requirements would effectively require self-conforming protocols anyway, since 
your function will have to dynamically handle both cases.

The implementation for self-conforming opaque protocols is not difficult, 
because the value itself can already be of any size, so it’s really not a 
problem to have an existential in there. In theory, someone could cook it up in 
a week or so.

For class protocols, I don’t know how to do it without an efficiency hit 
unfortunately.

Consider these two functions, taking a homogeneous and heterogeneous array of a 
class-bound protocol type:

protocol P : class {}

func f(array: [T]) {} // this takes an array of pointers to T, because 
there’s only one witness table for all of them
func ff(array: [P]) {} // this takes an array of  pairs, two 
pointers each, because each element can be a different concrete type

What you’re saying is that f() should in fact allow both representations, 
because you’ll be able to call f() with a value of type [P]. Right now, if we 
know a generic parameter is class-constrained, we use a much more efficient 
representation for values of that type, that is known to be fixed size in the 
LLVM IR. We would have to give that up to allow class-constrained existentials 
to self-conform, since now a class-constrained parameter can be an existential 
with any number of witness tables.

There might be some trick for doing this efficiently, but I don’t know of one 
yet.

Of course, we can just say that class-constrained protocols never self-conform, 
unless they’re @objc. That seems like a hell of an esoteric restriction though 
(can you imagine trying to come up with a clear phrasing for *that* diagnostic?)

And if you’re wondering, the reason that @objc protocols self-conform in Swift 
today, is because they their existentials don’t have *any* witness tables — 
@objc protocol method bodies are found by looking inside the instance itself.

AnyObject is the other kind of protocol that self-conforms — you can use it 
both as a generic constraint, and as a concrete type bound to a 

Re: [swift-evolution] try? shouldn't work on non-method-call

2016-08-18 Thread Slava Pestov via swift-evolution

> On Aug 18, 2016, at 12:52 AM, David Hart via swift-evolution 
>  wrote:
> 
> Opinions inline:
> 
>> On 18 Aug 2016, at 07:43, Sikhapol Saijit via swift-evolution 
>> > wrote:
>> 
>> Hi all,
>> 
>> 
>> Yesterday I tried this code:
>> 
>> func couldFailButWillNot() throws -> Any {
>> return 42
>> }
>> 
>> if let a = try? couldFailButWillNot() as? Int {
>> print(a)
>> }
>> 
>> And was surprised that the output was Optional(42) on both Swift 2 and Swift 
>> 3.
>> I always have the impression that when a variable is resolved with if let it 
>> will never be optional.
>> 
>> So, with a little investigation, I found out that it happens because as? has 
>> higher precedence than try? and is evaluated first.
>> And the whole expression `try? couldFailButWillNot() as? Int` evaluated as 
>> Optional(Optional(42)).
>> 
>> Also, I’m surprised that try? can be used with non-method-call.
>> This code: `print(try? 42)` will print Optional(42).
>> 
>> So, the questions are:
>> 
>> 1. Is it intentional that try? can be used with a "non-method-call" and 
>> return an optional of the type that follows?
> 
> I think this is the real solution. try and try? should not be allowed on 
> non-throwing functions or expressions.

This is a warning right now — do you think it should be an error?

Slavas-MacBook-Pro:~ slava$ cat ttt.swift 
func f() {}

func g() {
  try f()
  try? f()
}

Slavas-MacBook-Pro:~ slava$ swiftc ttt.swift 
ttt.swift:4:3: warning: no calls to throwing functions occur within 'try' 
expression
  try f()
  ^
ttt.swift:5:8: warning: no calls to throwing functions occur within 'try' 
expression
  try? f()
   ^

> 
>> 2. Should we design try? to have higher precedence than as? or any operators 
>> at all?
>> My intuition tells me that 
>> let a = try? couldFailButWillNot() as? Int
>> should be equivalent to
>> let a = (try? couldFailButWillNot()) as? Int 
> 
> That’s worth considering. try feels like it should tie very strongly with the 
> throwing expression.
> 
>> 3. Do you think that doubly-nested optional (or multi-level-nested optional) 
>> is confusing and should be removed from Swift? (Yes, I’ve seen this blog 
>> post Optionals Case Study: valuesForKeys 
>> ).
>> For me Optional(nil) (aka Optional.Some(Optional.None))) doesn’t make much 
>> sense. 
>> Maybe, one of the solution is to always have optional of optional merged 
>> into a single level optional? Like Optional(Optional(Optional(42))) should 
>> be the merged to and evaluated as Optional(42).
> 
> I don’t think this is the solution. Even if it was, how would you expect to 
> “remove” them from Swift? Optionals are simply an enum with an associated 
> value. We’d have to introduce a language feature to restrict values that can 
> be stored in enum cases? It sounds awfully complicated.
> 
>> BTW, the code above is merely for a demonstration. The actual code was more 
>> of something like this:
>> 
>> func parse(JSON: Data) throws -> Any {
>> // …
>> }
>> 
>> if let dict = try? parse(JSON: json) as? [String: Any] {
>> // assume dict is a valid [String: Any] dictionary
>> // …
>> }
>> 
>> I’m new to this mailing list so I’m not sure if this belongs here. I’m sorry 
>> in advance if it doesn’t.
>> 
>> 
>> Thank you,
>> Sam
>> ___
>> 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] try? shouldn't work on non-method-call

2016-08-18 Thread Slava Pestov via swift-evolution

> On Aug 18, 2016, at 1:42 AM, Slava Pestov via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
>> 
>> On Aug 18, 2016, at 12:52 AM, David Hart via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Opinions inline:
>> 
>>> On 18 Aug 2016, at 07:43, Sikhapol Saijit via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi all,
>>> 
>>> 
>>> Yesterday I tried this code:
>>> 
>>> func couldFailButWillNot() throws -> Any {
>>> return 42
>>> }
>>> 
>>> if let a = try? couldFailButWillNot() as? Int {
>>> print(a)
>>> }
>>> 
>>> And was surprised that the output was Optional(42) on both Swift 2 and 
>>> Swift 3.
>>> I always have the impression that when a variable is resolved with if let 
>>> it will never be optional.
>>> 
>>> So, with a little investigation, I found out that it happens because as? 
>>> has higher precedence than try? and is evaluated first.
>>> And the whole expression `try? couldFailButWillNot() as? Int` evaluated as 
>>> Optional(Optional(42)).
>>> 
>>> Also, I’m surprised that try? can be used with non-method-call.
>>> This code: `print(try? 42)` will print Optional(42).
>>> 
>>> So, the questions are:
>>> 
>>> 1. Is it intentional that try? can be used with a "non-method-call" and 
>>> return an optional of the type that follows?
>> 
>> I think this is the real solution. try and try? should not be allowed on 
>> non-throwing functions or expressions.
> 
> This is a warning right now — do you think it should be an error?
> 
> Slavas-MacBook-Pro:~ slava$ cat ttt.swift 
> func f() {}
> 
> func g() {
>   try f()
>   try? f()
> }
> 
> Slavas-MacBook-Pro:~ slava$ swiftc ttt.swift 
> ttt.swift:4:3: warning: no calls to throwing functions occur within 'try' 
> expression
>   try f()
>   ^
> ttt.swift:5:8: warning: no calls to throwing functions occur within 'try' 
> expression
>   try? f()
>^

… Replying to myself: I also think it would be more logical for this to be an 
error, but I vaguely recall some internal discussion where we agreed that 
removing ‘throws’ from a function should not break source or binary 
compatibility (I don’t know if the current implementation makes good on the 
latter).

Jordan, do you remember the reasoning for this being a warning and not an error?

> 
>> 
>>> 2. Should we design try? to have higher precedence than as? or any 
>>> operators at all?
>>> My intuition tells me that 
>>> let a = try? couldFailButWillNot() as? Int
>>> should be equivalent to
>>> let a = (try? couldFailButWillNot()) as? Int 
>> 
>> That’s worth considering. try feels like it should tie very strongly with 
>> the throwing expression.
>> 
>>> 3. Do you think that doubly-nested optional (or multi-level-nested 
>>> optional) is confusing and should be removed from Swift? (Yes, I’ve seen 
>>> this blog post Optionals Case Study: valuesForKeys 
>>> <https://developer.apple.com/swift/blog/?id=12>).
>>> For me Optional(nil) (aka Optional.Some(Optional.None))) doesn’t make much 
>>> sense. 
>>> Maybe, one of the solution is to always have optional of optional merged 
>>> into a single level optional? Like Optional(Optional(Optional(42))) should 
>>> be the merged to and evaluated as Optional(42).
>> 
>> I don’t think this is the solution. Even if it was, how would you expect to 
>> “remove” them from Swift? Optionals are simply an enum with an associated 
>> value. We’d have to introduce a language feature to restrict values that can 
>> be stored in enum cases? It sounds awfully complicated.
>> 
>>> BTW, the code above is merely for a demonstration. The actual code was more 
>>> of something like this:
>>> 
>>> func parse(JSON: Data) throws -> Any {
>>> // …
>>> }
>>> 
>>> if let dict = try? parse(JSON: json) as? [String: Any] {
>>> // assume dict is a valid [String: Any] dictionary
>>> // …
>>> }
>>> 
>>> I’m new to this mailing list so I’m not sure if this belongs here. I’m 
>>> sorry in advance if it doesn’t.
>>> 
>>> 
>>> Thank you,
>>> Sam
>>> ___
>>> swift-evolution mailing list

Re: [swift-evolution] [Pitch] Nested types in protocols (and nesting protocols in types)

2016-10-24 Thread Slava Pestov via swift-evolution

> On Oct 17, 2016, at 11:35 AM, Karl via swift-evolution 
>  wrote:
> 
> 
>> On 17 Oct 2016, at 20:31, Adrian Zubarev via swift-evolution 
>> > wrote:
>> 
>> That’s also on the line: 
>> [https://github.com/apple/swift/blob/611fc78d28a5da97dd1bea40761b913b1077aef5/docs/GenericsManifesto.md#nested-generics
>>  
>> ](https://github.com/apple/swift/blob/611fc78d28a5da97dd1bea40761b913b1077aef5/docs/GenericsManifesto.md#nested-generics
>>  
>> )
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> 
>> Am 17. Oktober 2016 um 20:26:47, T.J. Usiyan (griotsp...@gmail.com 
>> ) schrieb:
>> 
>>> I want this feature. Both class in protocol and protocol in class could 
>>> clean up many relationships but I think that a blocking concern is "How 
>>> does this interact with generics?" Nesting types in generic types is 
>>> already disallowed and how different is this feature from that?
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> And even partially implemented, behind the flag 
> “-enable-experimental-nested-generic-types”. I don’t know what’s missing from 
> it, but it seemed to work in some simple cases last time I tried.

This flag implements nesting non-protocol generic types inside other 
non-protocol generic types, except for some bugs I need to fix before I can 
just enable this all by default.

However protocols nested inside types and types nested inside protocols is 
still not supported, because protocols introduce a separate series of issues 
involving associated types and the ’Self’ type.

The hard part of getting nested generics right is what to do if a nested type 
‘captures’ generic parameters of the outer type. For non-protocol types, the 
behavior here is pretty straightforward.

If we allow protocols to be nested inside other types, we have to decide what 
to do if the protocol ‘closes over’ generic parameters of the outer type. For 
example,

struct A {
  protocol P {
func requirement() -> T
  }
}

Presumably A.P and A.P are distinct types, and A.P has a hidden 
associated type corresponding to the type parameter ’T’?

The other case is problematic too — the nested type might refer to an 
associated type of the outer protocol:

protocol P {
  associatedtype A

  struct T {
var value: A
  }
}

Now writing P.T does not make sense, for the same reason that we cannot form an 
existential of type P.A. We could prohibit references to outer associated types 
of this form, or we could figure out some way to give it a meaning. If C is a 
concrete type conforming to P, then certainly C.T makes sense, for instance. 
Internally, the nested type A.T could have a hidden ‘Self’ generic type 
parameter, so that writing C.T is really the same as P.T.

Protocols nested inside protocols also have the same issue.

Also note that even with the experimental flag, generic types nested inside 
generic *functions* are not supported either. Here, again, the difficulty is 
with captured generic parameters. The semantics are clear but the 
implementation needs some work.

Slava

> 
> - 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] [Pitch] Nested types in protocols (and nesting protocols in types)

2016-10-24 Thread Slava Pestov via swift-evolution
Hi Karl,

I just saw your draft after sending my first reply earlier; I posted some 
additional comments on the gist.

Also I remembered that Jordan Rose and I were talking about this recently in 
the context of the ClangImporter, so I'm CCing him in case he wants to share 
some thoughts.

> On Oct 21, 2016, at 6:21 PM, Karl via swift-evolution 
>  wrote:
> 
> I had a go at writing this up formally:
> 
> https://gist.github.com/karwa/4c6bff75f8fa84b16df2c8caae97d622 
> 
> 
> Is there anything I missed?
> 
> - Karl
> 
>> On 17 Oct 2016, at 20:44, Adrian Zubarev > > wrote:
>> 
>> That option should not be disallowed. Here is a simple example you might 
>> want to build at some point:
>> 
>> protocol ProtocolName {
>>  
>> associatedtype AssociatedType
>> }
>> 
>> extension ProtocolName where AssociatedType == Int {
>>   
>> struct InnerType {}
>> }
>> 
>> 
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> 
>> Am 17. Oktober 2016 um 20:30:58, Karl via swift-evolution 
>> (swift-evolution@swift.org ) schrieb:
>> 
>>> Is your vision that each conforming type would have to provide its own 
>>> nested type as specified by the protocol?
>>> 
>>> Or could the protocol itself define a nested type and anything could use it?
>>> 
>>> protocol FloatingPoint: … {
>>> enum RoundingRule {
>>> // Do I put an implementation here?
>>> }
>>> }
>>> 
>>> No, types which are defined inside the protocol are implemented there. 
>>> Providing your own types to satisfy a conformance is what associated types 
>>> are for.
>>> 
>>> If you wanted something like that, you could do it with a nested protocol + 
>>> associated type:
>>> 
>>> protocol FloatingPoint {
>>> 
>>> protocol _RoundingRule { func round(_ : Super) -> Super }
>>> associatedType RoundingRule : _RoundingRule
>>> }
>>> 
>>> struct Float : FloatingPoint {
>>> 
>>> enum RoundingRule : _RoundingRule {
>>> func round(_ val: Float) -> Float {
>>> /* switch self, perform rounding… */ 
>>> }
>>> }
>>> }
>>> 
>>> That brings up an interesting point, though - we would need a way to refer 
>>> to the outer protocol (I used “Super” here).
>>> 
>> 
>> 
> 
> ___
> 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] Nested types in protocols (and nesting protocols in types)

2016-11-02 Thread Slava Pestov via swift-evolution

> On Nov 2, 2016, at 8:32 AM, Paul Cantrell <cantr...@pobox.com> wrote:
> 
> 
>> On Oct 24, 2016, at 4:43 PM, Slava Pestov <spes...@apple.com> wrote:
>> 
>> 
>>> On Oct 24, 2016, at 8:12 AM, Paul Cantrell <cantr...@pobox.com> wrote:
>>> 
>>> 
>>>> On Oct 24, 2016, at 5:09 AM, Slava Pestov via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> However protocols nested inside types and types nested inside protocols is 
>>>> still not supported, because protocols introduce a separate series of 
>>>> issues involving associated types and the ’Self’ type.
>>>> 
>>>> The hard part of getting nested generics right is what to do if a nested 
>>>> type ‘captures’ generic parameters of the outer type. For non-protocol 
>>>> types, the behavior here is pretty straightforward.
>>>> 
>>>> If we allow protocols to be nested inside other types, we have to decide 
>>>> what to do if the protocol ‘closes over’ generic parameters of the outer 
>>>> type. For example,
>>>> 
>>>> struct A {
>>>> protocol P {
>>>>  func requirement() -> T
>>>> }
>>>> }
>>>> 
>>>> Presumably A.P and A.P are distinct types, and A.P has a 
>>>> hidden associated type corresponding to the type parameter ’T’?
>>>> 
>>>> The other case is problematic too — the nested type might refer to an 
>>>> associated type of the outer protocol:
>>>> 
>>>> protocol P {
>>>> associatedtype A
>>>> 
>>>> struct T {
>>>>  var value: A
>>>> }
>>>> }
>>>> 
>>>> Now writing P.T does not make sense, for the same reason that we cannot 
>>>> form an existential of type P.A. We could prohibit references to outer 
>>>> associated types of this form, or we could figure out some way to give it 
>>>> a meaning. If C is a concrete type conforming to P, then certainly C.T 
>>>> makes sense, for instance. Internally, the nested type A.T could have a 
>>>> hidden ‘Self’ generic type parameter, so that writing C.T is really the 
>>>> same as P.T.
>>>> 
>>>> Protocols nested inside protocols also have the same issue.
>>> 
>>> FWIW, in almost all the situations where I’ve wanted to nest types inside 
>>> protocols and generic types, it’s only as a namespacing convenience. Most 
>>> often, it’s an enum type that’s used only by a single method, and having it 
>>> at the top of the module namespace adds clutter.
>>> 
>>> Here’s a real life example pared down. I wish I could do this:
>>> 
>>>  public struct ResponseContentTransformer<InputContentType, 
>>> OutputContentType>: ResponseTransformer {
>>> 
>>>public init(onInputTypeMismatch mismatchAction: InputTypeMismatchAction 
>>> = .error) {
>>>  ...
>>>}
>>> 
>>>public enum InputTypeMismatchAction {  // Does not depend on generic 
>>> types above
>>>  case error
>>>  case skip
>>>  case skipIfOutputTypeMatches
>>>}
>>> 
>>>  }
>>> 
>>> InputTypeMismatchAction is tightly associated with 
>>> ResponseContentTransformer, and is confusing as a top-level type.
>>> 
>>> What do you think about providing a “no captures” modifier for nested types 
>>> — like static inner classes in Java? Then Swift could provide the namespace 
>>> nesting I wish for this without having to resolve the trickier type capture 
>>> questions yet.
>>> 
>>> Alternatively, what if (1) outer types aren’t capture unless they’re 
>>> referenced, and (2) nesting is only illegal if there’s a capture? Then my 
>>> code above would compile, as would this:
>>> 
>>>  public struct S {
>>>public enum Foo {
>>>  case yin
>>>  case yang
>>>}
>>>  }
>>> 
>>> …but this wouldn’t:
>>> 
>>>  public struct S {
>>>public enum Foo {
>>>  case yin(thing: T)  // capture of T illegal (for now)
>>>  case yang
>>>}
>>>  }
>>> 
>>> Either of these approaches would allow hygienic namespacing now while 
>>> leaving the door open to outer type capture in the future.
>> 
>> Yeah, this makes sense for a first cut at this feature.
>> 
>> Slava
> 
> Should I take a crack at writing up a proposal for this? Now? After ABI work 
> is done? (Probably the latter “OK if no captures” approach?) Eager to help; 
> don’t want to be in the way.

Just speaking for myself and not the whole team — I think you can submit the 
proposal at any time, we’re unlikely to get around to doing it, if you want to 
take a crack that would be great (again, with ‘no captures’ it’s “trivial”).

Slava

> 
> P
> 

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


Re: [swift-evolution] [Pitch] Simpler interpretation of a reference to a generic type with no arguments

2016-10-11 Thread Slava Pestov via swift-evolution
I could if there’s interest. Since we intend on maintaining source 
compatibility, it will not result in a simpler implementation, though, since 
we’ll need to keep the old code path around for Swift 3 mode. Still worth it?

Slava

> On Oct 11, 2016, at 1:58 PM, Pyry Jahkola  wrote:
> 
> I was reminded of this proposal which seems like an obvious win in clarity. 
> Still planning to submit it, Slava?
> 
> — Pyry
> 
>> On 28 Jun 2016, at 21:13, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> on Thu Jun 23 2016, Slava Pestov  wrote:
>> 
>>> Simpler interpretation of a reference to a generic type with no
>>> arguments
>>> 
>>> Proposal: SE-
>>> 
>>> Author: Slava Pestov 
>>> Status: Awaiting review
>>> Review manager: TBD
>>> Introduction
>>> 
>>> This proposal cleans up the semantics of a reference to a generic type
>>> when no generic arguments are applied.
>>> 
>>> Swift-evolution thread: Discussion thread topic for that proposal
>>> 
>>> Motivation
>>> 
>>> Right now, we allow a generic type to be referenced with no generic
>>> arguments applied in a handful of special cases. The two primary rules
>>> here are the following:
>>> 
>>> If the scope from which the reference is made is nested inside the
>>> definition of the type or an extension thereof, omitting generic
>>> arguments just means to implicitly apply the arguments from context.
>>> 
>>> For example,
>>> 
>>> struct GenericBox {
>>> let contents: Contents
>>> 
>>> // Equivalent to: func clone() -> GenericBox
>>> func clone() -> GenericBox {
>>>   return GenericBox(contents: contents)
>>> }
>>> }
>>> 
>>> extension GenericBox {
>>> func print() {
>>>   // Equivalent to: let cloned: GenericBox
>>>   let cloned: GenericBox = clone()
>>>   print(cloned.contents)
>>> }
>>> }
>>> If the type is referenced from an unrelated scope, we attempt to infer
>>> the generic parameters.
>>> 
>>> For example,
>>> 
>>> func makeABox() -> GenericBox {
>>> // Equivalent to: GenericBox(contents: 123)
>>> return GenericBox(contents: 123)
>>> }
>>> The problem appears when the user expects the second behavior, but
>>> instead encounters the first. For example, the following does not type
>>> check:
>>> 
>>> extension GenericBox {
>>> 
>>> func transform(f: Contents -> T) -> GenericBox {
>>>   // We resolve 'GenericBox' as 'GenericBox', rather than
>>>   // inferring the type parameter
>>>   return GenericBox(contents: f(contents))
>>> }
>>> }
>>> Proposed
>>> solution
>>> 
>>> The proposed solution is to remove the first rule altogether. If the
>>> generic parameters cannot be inferred from context, they must be
>>> specified explicitly with the usual Type syntax.
>> 
>> SGTM.  I've always found this shorthand to be somewhat surprising,
>> including in C++ where (IIUC) it originated.
>> 
>> 
>> -- 
>> Dave
> 

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


Re: [swift-evolution] Generic Subscripts

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

> On Jan 11, 2017, at 10:53 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>> 
>> On Jan 11, 2017, at 12:32 PM, Erica Sadun via swift-evolution 
>> > wrote:
>> 
>> 
>>> On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
>>> On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
>>> > wrote:
> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
> > wrote:
> 
> [Forgot to CC swift-evolution the first time]
> 
> When this came up last, it was seen as more so a bug in the current 
> implementation, rather than an explicit choice. There's no need for a 
> proposal, just a JIRA: 
> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>  
> 
>  
 
 It’s a nontrivial new user-facing feature with new syntax in the language, 
 so it’ll need a proposal. ‘twould be good for the proposal to link to the 
 JIRA ticket.
 
 I’ve only heard positive reactions toward this feature, and it’s something 
 that the standard library could make good use of.
>>> 
>>> +1, this would be clearly great to happen.
>>> 
>>> -Chris
>> 
>> 
>> I apologize for adding to this topic rather than starting a new one, but I 
>> figure people interested in subscripts would be more likely to see my 
>> question:
>> 
>> Is there a good reason subscripts cannot throw? Right now you can create a 
>> [safe: index] subscript to return an optional but you can't create one that 
>> returns an unwrapped value or throws.
> 
> These topics do tend to come up together they are the two unnecessary 
> limitations subscripts have right now.  I hope both make it into Swift 4.  
> I’m sure we’ll see a proposal after phase 2 opens up.

Another limitation is that subscripts cannot have default arguments. I don’t 
believe this even requires an evolution proposal, it’s a quirk of the 
implementation and can be fixed by cleaning up some duplicated code paths in 
SILGen. If anyone is interested in looking at this I can point you to the code 
in question.

Slava

> 
>> 
>> Thanks, -- E
>> 
>> ___
>> 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] Equatability for enums with associated values

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

> On Jan 13, 2017, at 1:15 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> This is a request that comes up frequently; I wrote an early draft proposal 
> for it several months ago, with it covering all value types, not just enums, 
> and also including Hashable as well as Equatable:
> 
> https://gist.github.com/allevato/2fd10290bfa84accfbe977d8ac07daad 
> 
> 
> Since it's purely additive, it won't get much attention until phase 2 at the 
> earliest, but I'd like to revisit it then. Most of the discussion before 
> revolved around to what degree users should have to opt-in or opt-out of this 
> functionality.

I think if someone were to implement this though, we would be happy to merge it 
in. The code for deriving Equatable and Hashable conformances is in these files:

lib/Sema/CodeSynthesis.cpp
lib/Sema/DerivedConformances.cpp
lib/Sema/DerivedConformanceEquatableHashable.cpp

I agree it should be opt-in though (I would also argue that even the no-payload 
enum behavior should be opt-in, but that ship has sailed).

> 
> Re: generics, I don't think there's anything on the roadmap that goes into 
> such deep detail as "if every associated value of every enum case is 
> Equatable, then X is also Equatable", and I don't think there would be a 
> clean way to express that with the generics syntax. This would probably have 
> to be something that's baked into the compiler to synthesize == and hashValue 
> for types that satisfy the constraints.

The generics feature people are thinking of is conditional conformances:

extension Array : Equatable where Element == Equatable { … }

However it does not solve the problem for enums with associated values because 
as you said there’s no way to quantify over ‘all associated values’ in the 
language, and this is not planned.

Slava

> 
> 
> On Fri, Jan 13, 2017 at 12:31 PM David Sweeris via swift-evolution 
> > wrote:
> 
> 
> 
> Sent from my iPhone
> On Jan 13, 2017, at 13:51, Adam Shin via swift-evolution 
> > wrote:
> 
>> When using enums with associated values, it's often necessary to check for 
>> equality between two enum objects in some way. That can lead to boilerplate 
>> code like this:
>> 
>> enum Option {
>> case foo(String)
>> case bar(Int)
>>  case zip
>> }
>> 
>> func ==(lhs: Option, rhs: Option) -> Bool {
>> switch (lhs, rhs) {
>> case (.foo(let a), .foo(let b)) where a == b: return true
>> case (.bar(let a), .bar(let b)) where a == b: return true
>> case (.zip, .zip): return true
>> default: return false
>> }
>> }
>> 
>> ..which results in code duplication and opens the door to potential logic 
>> errors.
>> 
>> Instead, what if enums with associated values were automatically Equatable 
>> when all their associated values were Equatable? That would remove the need 
>> for such boilerplate code.
>> 
>> The Swift language guide states that custom classes and structs don't 
>> receive a default implementation of the == operator because the compiler 
>> can't guess what "equality" means for them. However, I think this could make 
>> sense for enums. An enum case, even with associated values, seems closer to 
>> a value itself than an object with logic and state.
>> 
>> I'd be interested to hear any thoughts on this. Would this be a beneficial 
>> addition?
> 
> I think it makes more sense to come up with some syntax for reducing that 
> kind of boilerplate code in general. In "pseudo-english", I'd write the == 
> function as "if lhs and rhs are the same case && their associated values are 
> the equal, return true, else return false".
> 
> What about doing something with the reflection system? Isn't that supposed to 
> get overhauled for Swift 4? I'm not sure what the performance implications 
> would be, though.
> 
> - Dave Sweeris 
> ___
> 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] Equatability for enums with associated values

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

> On Jan 13, 2017, at 12:14 PM, Jonathan Hull via swift-evolution 
>  wrote:
> 
> I think the “when all their associated values were Equatable” is the 
> technical issue holding this type of thing up.  The ability to spell that 
> type of thing is on the generics roadmap, but I don’t know when it will 
> actually happen.  There seem to be a lot of things on hold because of it.

The proposal for conditional conformances was accepted. However, right now the 
generics feature being worked on is recursive conformances, together with a 
large overall cleanup of the generics implementation to fix bugs and improve 
correctness. Conditional conformances will come at some point after that.

Slava

> 
> Thanks,
> Jon
> 
>> On Jan 13, 2017, at 11:51 AM, Adam Shin via swift-evolution 
>> > wrote:
>> 
>> When using enums with associated values, it's often necessary to check for 
>> equality between two enum objects in some way. That can lead to boilerplate 
>> code like this:
>> 
>> enum Option {
>> case foo(String)
>> case bar(Int)
>>  case zip
>> }
>> 
>> func ==(lhs: Option, rhs: Option) -> Bool {
>> switch (lhs, rhs) {
>> case (.foo(let a), .foo(let b)) where a == b: return true
>> case (.bar(let a), .bar(let b)) where a == b: return true
>> case (.zip, .zip): return true
>> default: return false
>> }
>> }
>> 
>> ..which results in code duplication and opens the door to potential logic 
>> errors.
>> 
>> Instead, what if enums with associated values were automatically Equatable 
>> when all their associated values were Equatable? That would remove the need 
>> for such boilerplate code.
>> 
>> The Swift language guide states that custom classes and structs don't 
>> receive a default implementation of the == operator because the compiler 
>> can't guess what "equality" means for them. However, I think this could make 
>> sense for enums. An enum case, even with associated values, seems closer to 
>> a value itself than an object with logic and state.
>> 
>> I'd be interested to hear any thoughts on this. Would this be a beneficial 
>> addition?
>> ___
>> 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] Equatability for enums with associated values

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

> On Jan 13, 2017, at 2:30 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> On Jan 13, 2017, at 15:10, Anton Zhilin via swift-evolution 
> > wrote:
> 
>> That seems pretty close to Rust’s derive. Why not invent a similar syntax in 
>> Swift? Otherwise it will make us look through all the sources to make sure 
>> deriving is used.
>> 
>> enum Option: @derive Equatable {
>> ...
>> }
>> Also, we can get better looking compilation errors, like:
>> 
>> ERROR at line 1, col 14: could not derive Equatable for Option
>> enum Option: @derive Equatable {
>>  ^
> 
> I think that idea came up once before... can't remember where, though, or 
> what we thought of it at the time.
> 
> As far as reducing enum boilerplate, what about borrowing the generic 
> system's syntax and looking at it from the switch's PoV?
> func == (lhs: MyEnum, rhs: MyEnum) -> Bool {
> switch  (lhs, rhs) {
> case (c(let lVal), c(let rVal)): // both lhs and rhs are "c" and the same 
> case
> return lVal == rVal //syntax error if `==` isn't defined for the 
> associated value types of every case
> default: return false
> }
> }

I think initially, we would like to implement deriving these witnesses directly 
in the compiler, instead of trying to come up with a metaprogramming syntax for 
them.

Slava

> 
> - Dave Sweeris
> ___
> 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] Generic Subscripts

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

> On Jan 12, 2017, at 7:05 PM, Karl Wagner <razie...@gmail.com> wrote:
> 
> 
>> On 12 Jan 2017, at 22:37, Slava Pestov via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Jan 12, 2017, at 9:53 AM, Chris Eidhof via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Ok, I've got a draft up as a gist: 
>>> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
>>> <https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25>
>>> 
>>> Before I submit it, could someone let me know if adding generics to 
>>> subscripts would influence the ABI? ( still feel pretty clueless in that 
>>> area).
>> 
>> It won’t change the ABI of existing subscript calls, but if the standard 
>> library introduces new generic subscripts that replace older non-generic 
>> subscripts, it will impact ABI.
>> 
>> Slava
> 
> Why are subscripts so different, anyway? One would think they are basically 
> sugared functions, but they don’t support so many things that regular 
> functions support. Not just syntax stuff, either - they also don’t support 
> @inline(__always) for some reason…

Nice catch with @inline(__always). Please file a JIRA issue, since I’m actively 
working on this stuff now.

Subscripts are a bit different from ordinary functions because they’re lvalues. 
You can call mutating members on the result of a subscript, or chain it with 
another property access or subscript. So the code path in SILGen is a little 
different than ordinary function calls. This is the reason subscripts cannot 
have default arguments also. With a bit of refactoring we can unify the code 
path for forming call arguments in ordinary calls and subscripts, and hopefully 
the default argument and generic cases will fall out naturally also.

> 
> Where generic subscripts are concerned, there are a couple of different 
> things to express:
> - Generic parameter  (I can understand various co-ordinates for the data)
> - Generic return type (I can construct your preferred representation of the 
> data)
> - Generic setter type (I can set the data using various compatible types):

I think all of these should be expressed with a single generic signature on the 
subscript itself. The element type passed to the setter and returned from the 
getter should be the same IMO, otherwise it’s not clear how it will work.

> 
> protocol MeaningfulToFoo {}
> protocol ConstructableFromFoo {}
> 
> struct Foo {
> subscript(index: Index) where Index: SignedInteger {
> get where T: ConstructableFromFoo { return T(self) }
> set where T: MeaningfulToFoo  { self.someProperty = 
> newValue.someData }
> }
> }
> 
> The syntax looks a bit awkward, though, IMO. I’m wondering if it might be 
> better to have some kind of combined subscript + property behaviours 
> (remember those?) and allow those to be generic instead. Subscripts and 
> properties are very similar anyway - they are both bundles of functions to 
> represent getting and setting data (not just regular-old “get” and “set”, 
> either, but also magic stuff like “mutableAddressWithPinnedNativeOwner”). The 
> only difference is that property getters can’t have parameters — which is 
> something I would also like to see lifted one day (I believe I’ve even seen 
> people asking for “named subscripts” due to the lack of this =P)
> 
> - Karl
> 

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


Re: [swift-evolution] Generic Subscripts

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

> On Jan 12, 2017, at 9:53 AM, Chris Eidhof via swift-evolution 
>  wrote:
> 
> Ok, I've got a draft up as a gist: 
> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
> 
> 
> Before I submit it, could someone let me know if adding generics to 
> subscripts would influence the ABI? ( still feel pretty clueless in that 
> area).

It won’t change the ABI of existing subscript calls, but if the standard 
library introduces new generic subscripts that replace older non-generic 
subscripts, it will impact ABI.

Slava

> 
> Thanks!
> 
> On Thu, Jan 12, 2017 at 8:57 AM, Douglas Gregor via swift-evolution 
> > wrote:
> 
> 
> Sent from my iPhone
> 
> On Jan 11, 2017, at 11:05 PM, Chris Eidhof via swift-evolution 
> > wrote:
> 
>> Okay,
>> 
>> I agree that throwing subscripts would be great to have. Likewise, 
>> generic(and maybe even throwing) properties could be useful. However, I 
>> think that for this proposal, it makes more sense to focus on just generic 
>> subscripts, and mention throwing subscripts as "future improvements"? 
> 
> There's already a draft proposal covering throwing subscripts. You can 
> mention it's existence, but I don't see a reason to say much. 
> 
>  - Doug
> 
> 
>> 
>> On Wed, Jan 11, 2017 at 8:52 PM, John McCall via swift-evolution 
>> > wrote:
>>> On Jan 11, 2017, at 1:32 PM, Erica Sadun via swift-evolution 
>>> > wrote:
 On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
 > wrote:
 
 On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
 > wrote:
>> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
>> > wrote:
>> 
>> [Forgot to CC swift-evolution the first time]
>> 
>> When this came up last, it was seen as more so a bug in the current 
>> implementation, rather than an explicit choice. There's no need for a 
>> proposal, just a JIRA: 
>> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>>  
>> 
>>  
> 
> It’s a nontrivial new user-facing feature with new syntax in the 
> language, so it’ll need a proposal. ‘twould be good for the proposal to 
> link to the JIRA ticket.
> 
> I’ve only heard positive reactions toward this feature, and it’s 
> something that the standard library could make good use of.
 
 +1, this would be clearly great to happen.
 
 -Chris
>>> 
>>> 
>>> I apologize for adding to this topic rather than starting a new one, but I 
>>> figure people interested in subscripts would be more likely to see my 
>>> question:
>>> 
>>> Is there a good reason subscripts cannot throw? Right now you can create a 
>>> [safe: index] subscript to return an optional but you can't create one that 
>>> returns an unwrapped value or throws.
>> 
>> Throwing accessors are mostly straightforward, but there is a big conceptual 
>> question: what happens if an accessor is called during error propagation?  
>> For example:
>> 
>>   objectWithThrowingSubscriptSetter[index].mutatingMethodThatCanThrow()
>> 
>> If the method throws, we currently still call the setter in order to finish 
>> the access.  If the setter can throw, then, we might end up with multiple 
>> errors being thrown at the same time, which isn't good — the language is put 
>> in the awkward position of having to invent an arbitrary resolution 
>> mechanism.
>> 
>> You might ask: why do we call the setter if an error is thrown?  Well, it's 
>> complicated.  One reason is that the implementation technique we use for 
>> generic access to subscripts and properties — accesses where we don't know 
>> how the subscript/property is implemented — doesn't know how to distinguish 
>> between *finishing* an access normally and *aborting* an access abnormally.  
>> Some kinds of property/subscript implementation — ones currently reserved 
>> for the standard library, but likely to be eventually offered to users in 
>> some form — depend on doing extra work no matter how the access is 
>> terminated, e.g. to release a buffer pointer.  (In fact, in general this 
>> applies even to get/set implementations, because even if we decided not to 
>> call the setter when an error was thrown, we would at least need to destroy 
>> the index argument that we were going to pass to the setter.)  In order to 
>> get consistent behavior between generic and 

Re: [swift-evolution] Generic Subscripts

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

> On Jan 12, 2017, at 9:56 AM, Gwendal Roué via swift-evolution 
>  wrote:
> 
> Hello Chris, thanks for this draft!
> 
> May I suggest that the introduction mentions genericity on return type as 
> well?
> 
> subscript(_ index: Int) -> T
> 
> (I have database rows in mind.)

Yeah, there’s no reason to restrict it to either just the index or element type.

Slava

> 
> Gwendal
> 
>> Le 12 janv. 2017 à 18:53, Chris Eidhof via swift-evolution 
>> > a écrit :
>> 
>> Ok, I've got a draft up as a gist: 
>> https://gist.github.com/chriseidhof/6c681677d44903045587bf75fb17eb25 
>> 
>> 
>> Before I submit it, could someone let me know if adding generics to 
>> subscripts would influence the ABI? ( still feel pretty clueless in that 
>> area).
>> 
>> Thanks!
>> 
>> On Thu, Jan 12, 2017 at 8:57 AM, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>> 
>> Sent from my iPhone
>> 
>> On Jan 11, 2017, at 11:05 PM, Chris Eidhof via swift-evolution 
>> > wrote:
>> 
>>> Okay,
>>> 
>>> I agree that throwing subscripts would be great to have. Likewise, 
>>> generic(and maybe even throwing) properties could be useful. However, I 
>>> think that for this proposal, it makes more sense to focus on just generic 
>>> subscripts, and mention throwing subscripts as "future improvements"? 
>> 
>> There's already a draft proposal covering throwing subscripts. You can 
>> mention it's existence, but I don't see a reason to say much. 
>> 
>>  - Doug
>> 
>> 
>>> 
>>> On Wed, Jan 11, 2017 at 8:52 PM, John McCall via swift-evolution 
>>> > wrote:
 On Jan 11, 2017, at 1:32 PM, Erica Sadun via swift-evolution 
 > wrote:
> On Jan 11, 2017, at 12:26 AM, Chris Lattner via swift-evolution 
> > wrote:
> 
> On Jan 10, 2017, at 11:40 AM, Douglas Gregor via swift-evolution 
> > wrote:
>>> On Jan 10, 2017, at 10:34 AM, Michael Ilseman via swift-evolution 
>>> > wrote:
>>> 
>>> [Forgot to CC swift-evolution the first time]
>>> 
>>> When this came up last, it was seen as more so a bug in the current 
>>> implementation, rather than an explicit choice. There's no need for a 
>>> proposal, just a JIRA: 
>>> https://bugs.swift.org/browse/SR-115?jql=text%20~%20%22Generic%20subscript%22
>>>  
>>> 
>>>  
>> 
>> It’s a nontrivial new user-facing feature with new syntax in the 
>> language, so it’ll need a proposal. ‘twould be good for the proposal to 
>> link to the JIRA ticket.
>> 
>> I’ve only heard positive reactions toward this feature, and it’s 
>> something that the standard library could make good use of.
> 
> +1, this would be clearly great to happen.
> 
> -Chris
 
 
 I apologize for adding to this topic rather than starting a new one, but I 
 figure people interested in subscripts would be more likely to see my 
 question:
 
 Is there a good reason subscripts cannot throw? Right now you can create a 
 [safe: index] subscript to return an optional but you can't create one 
 that returns an unwrapped value or throws.
>>> 
>>> Throwing accessors are mostly straightforward, but there is a big 
>>> conceptual question: what happens if an accessor is called during error 
>>> propagation?  For example:
>>> 
>>>   objectWithThrowingSubscriptSetter[index].mutatingMethodThatCanThrow()
>>> 
>>> If the method throws, we currently still call the setter in order to finish 
>>> the access.  If the setter can throw, then, we might end up with multiple 
>>> errors being thrown at the same time, which isn't good — the language is 
>>> put in the awkward position of having to invent an arbitrary resolution 
>>> mechanism.
>>> 
>>> You might ask: why do we call the setter if an error is thrown?  Well, it's 
>>> complicated.  One reason is that the implementation technique we use for 
>>> generic access to subscripts and properties — accesses where we don't know 
>>> how the subscript/property is implemented — doesn't know how to distinguish 
>>> between *finishing* an access normally and *aborting* an access abnormally. 
>>>  Some kinds of property/subscript implementation — ones currently reserved 
>>> for the standard library, but likely to be eventually offered to users in 
>>> some form — depend on doing extra work no matter how the access is 
>>> 

Re: [swift-evolution] Best way to handle escaping function that might throw

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

> On Jan 11, 2017, at 2:02 PM, Howard Lovatt via swift-evolution 
>  wrote:
> 
> Another possibility, other than generics, would be to drop rethrows all 
> together and have the compiler infer if a throw is possible or not, including:
> 
> struct FStore {
> let f: () throws -> Void
> func call() throws { try f() }
> }
> 
> The compiler can make two versions, one if f can throw and one if it 
> definitely doesn't. 

It seems that this approach is impractical, because you either have to compile 
two versions of every function, or make all function bodies available for 
inlining, which is a non-starter for a stable ABI.

Slava

> 
> Just a thought. 
> 
> On Tue, 10 Jan 2017 at 4:29 pm, Jacob Bandes-Storch  > wrote:
> Moving to swift-users list.
> 
> No, there's no way to do this today. The point of rethrows is that within one 
> call site, "f(block)" can be treated as throwing if the block throws, or not 
> throwing if the block doesn't throw. In your example, once the FStore object 
> is constructed, the information about the original passed-in function is 
> lost, so the caller has no way to know whether call() can throw or not.
> 
> If this *were* possible, the information would somehow need to be encoded in 
> the type system when creating FStore(f: block). That would require something 
> like dependent typing, or generic-param-based-rethrows, e.g.
> 
> struct FStore Void> {  // made-up syntax
> let f: T
> func call() rethrows(T) { try f() }  // throws-ness of this function 
> depends on throws-ness of T
> }
> 
> 
> 
> On Mon, Jan 9, 2017 at 9:21 PM, Howard Lovatt via swift-evolution 
> > wrote:
> Hi,
> 
> If I have an escaping function that I store and then call, I need to declare 
> the calling function as throwing, not rethrowing. EG:
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> struct FStore {
> let f: () throws -> Void
> init(f: @escaping () throws -> Void) { self.f = f }
> func call() throws { try f() } // Can't put rethrows here - have to 
> use throws
> }
> 
> Is there a better solution?
> 
> Thanks for any suggestions,
> 
>   -- Howard.
> 
> 
> 
> 
> 
> ___
> 
> 
> swift-evolution mailing list
> 
> 
> swift-evolution@swift.org 
> 
> 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> 
> 
> 
> 
> 
> -- 
> -- Howard.
> ___
> 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


  1   2   3   >