Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Goffredo Marocchi via swift-evolution
Hey Brent,

Sorry for being a bit dense about this, but...

> 
>NSObject
>NSResponder: NSObject
>NSView: NSResponder
> 
> `Type` is a `Subtype`, but not a `Subtype`.
> 
> Thus, this reads correctly:
> 
>let aType: Subtype = NSView.self
> 
> Whereas this does not:
> 
>let aType: Supertype = NSView.self


Calling it SuperTypeOf and SubTypeOf would make it less confusing as that 
is how I read it in my mind in your last example.

Sent from my iPhone

On 30 Sep 2016, at 04:57, Brent Royal-Gordon via swift-evolution 
 wrote:

>> On Sep 29, 2016, at 8:14 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> I'm confused by this explanation.Today, `type(of:)` is the new 
>> `.dynamicType`. Is this proposal suggesting a silent change so that it now 
>> returns the static type? If so, why (particularly when you explain that this 
>> is often *not* what you would want)?
> 
> I'm short-handing the names to talk about the return values. In other words, 
> I assume that, if we have both `type(of:)` and `subtype(of:)`, their 
> signatures would be:
> 
>func type(of: T) -> Type
>func subtype(of: T) -> Subtype
> 
> And I'm saying that, given these names, `type(of:)` is confusing and 
> near-useless, whereas `subtype(of:)` is what you almost always want.
> 
> We *could*, of course, have a function called `type(of:)` which returned 
> `Subtype` and had the semantics I'm referring to as `subtype(of:)`. A name 
> is just a name.
> 
>> I'm also somewhat puzzled about the proposed design. This proposal explains 
>> that Subtype should be a supertype of Type and its subtypes. Why is a 
>> supertype named Subtype?
> 
> Because a type's name should describe the *instances*; that's why you don't 
> put "Class" at the end of all of your class names. (It's also why we're 
> proposing `Type` instead of `Metatype`.)
> 
> Every instance of `Subtype` is the type instance for a subtype of `T`. For 
> instance, in this hierarchy:
> 
>NSObject
>NSResponder: NSObject
>NSView: NSResponder
> 
> `Type` is a `Subtype`, but not a `Subtype`.
> 
> Thus, this reads correctly:
> 
>let aType: Subtype = NSView.self
> 
> Whereas this does not:
> 
>let aType: Supertype = NSView.self
> 
> -- 
> 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] [Pitch] Refactor Metatypes

2016-09-30 Thread Adrian Zubarev via swift-evolution
I’ll join the conversation tomorrow. Thanks to Brent for his huge contribution. 
:)

Just a quick side note:

Moving from T.Type and T.Protocol to Type and Subtype would also allow us 
to finally reuse and correctly nest our custom Type and Protocol types.
struct A {
   struct Type {}
}

A.Type() // <— Yeay
This proposal also aims to fix the problem with generics where any protocol 
metatype was converted to P.Protocol.


-- 
Adrian Zubarev
Sent with Airmail

Am 30. September 2016 um 06:22:34, Xiaodi Wu via swift-evolution 
(swift-evolution@swift.org) schrieb:

What does the proposal offer that goes beyond what we currently have?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pitch: Renaming CharacterSet to UnicodeScalarSet

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

on Wed Sep 28 2016, Erica Sadun  wrote:

> Chris: "Also, it is worth saying that any source breaking change still has to 
> have an 
> ultra-compelling reason to be worth considering.  Despite having a framework 
> to 
> support some source breaking changes, we still want to minimize them where 
> ever possible."
>
> Since it seems to be open season on introducing a few, highly focused
> breaking changes, let me throw this one out there.
>
> Pitch: Renaming CharacterSet to UnicodeScalarSet

Hi Erica,

This is out-of-scope for this list, because CharacterSet is part of
corelibs-foundation.  I suggest posting on
https://lists.swift.org/mailman/listinfo/swift-corelibs-dev, where the
Foundation people hang.

> In Swift, String is defined as "a Unicode string value." and a "CharacterSet" 
> represents a set of Unicode-compliant characters.
>
> A CharacterSet's initializers are:
> init()
> init(S)
> init(arrayLiteral: UnicodeScalar...)
> init(bitmapRepresentation: Data)
> init(charactersIn: ClosedRange)
> init(charactersIn: String)
> init(charactersIn: Range)
> init?(contentsOfFile: String)
>
> Why not rename `CharacterSet` to `UnicodeScalarSe`t, and update the 
> initializers
> to reflect they're being initialized from the unicode scalars in strings and 
> ranges?
> I think the few places where the word `character` is left mentioned (in 
> convenience
> properties) can be better named from `punctuationCharacters` to 
> `punctuation`, 
> `controlCharacters` to `controlAndFormat`, etc.
>
> -- E
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

-- 
-Dave

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


Re: [swift-evolution] [Pre-proposal] Enforcing Correct use of Array Indices

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

on Thu Sep 29 2016, Haravikk  wrote:

> So the issue of Array index safety came up on the discussion for the
> .indexed() proposal. Now of course there's nothing wrong with arrays
> using integers as indices as such, but it does mean that indices can
> be manipulated outside of the array, which somewhat defeats the idea
> of the indexing model requiring them to be passed back to the parent
> collection for manipulation.
>
> In a few types of my own I've avoided this problem by doing the
> following:
>
> public struct MyMaskedIndex : Comparable { fileprivate var raw:Int }
> // Comparable conformance omitted
>
> public struct MyType : Collection {
> // Lots of stuff omitted
> public func distance(from start:MyMaskedIndex, to
> end:MyMaskedIndex) -> Int {
> return end.raw - start.raw;
> }
> }
>
> In essence MaskedIndex is still just an Int, and should optimise as
> such, but in development the use of a type like this ensures that
> indices from my collection can't be manipulated externally, which
> enables the type-checker to conveniently prevent any mistakes I might
> make. It's a handy pattern for other things like hashed values,
> ensuring I can't use unhashed values of the same type by accident and
> so-on.

Yeah, but it doesn't really ensure you won't use an invalid index.
Among many other things, you can always reset the collection to an empty
state and all the old indices become invalid with respect to it.

> I just wanted to raise the topic to see what other people thought
> about the idea of doing something similar for Array and any other
> types that use integer types directly as indices? For convenience it
> is still possible to have a public initialiser on the masking type(s),
> so that custom values can be used, but by using MaskedIndex(raw:) it
> should be much more obvious what's happening.

Believe me, we considered this when doing the Array design.  Being able
to index an Array with Ints is pretty fundamental to its usability and
adoptability, and wrapping the index doesn't buy any real safety.

-- 
-Dave

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


Re: [swift-evolution] [Proposal draft] Conditional conformances

2016-09-30 Thread plx via swift-evolution

> On Sep 28, 2016, at 5:53 PM, Douglas Gregor  wrote:
> 
> 
>> On Sep 28, 2016, at 1:28 PM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> It’s good to see this starting to happen!
>> 
>> Is the decision on "no-overlapping-conformances” something that’s seen-as 
>> set in stone permanently, set in stone for the near future, or perhaps at 
>> least somewhat open to reconsideration at the present moment?
> 
> There hasn’t been a decision per se, so it that sense it’s open to 
> reconsideration.

I see. A related question: if overlapping conditional conformances are 
disallowed in Swift 4, would e.g. ABI concerns make it infeasible to relax that 
restriction in future Swift (5, 6, X, etc.)? 

FWIW my overall 2c is that the right move right now is to leave out overlapping 
conformances due to the complexity…as long as doing so now doesn’t 
realistically mean never being able to relax that restriction at some later 
date. I realize it’s always *possible* to relax it, so to try and be even 
clearer I really mean “possible to relax it without having to compromise on 
things like ABI-stability (etc.)”.

Also FWIW my suspicion is that in the absence of overlapping conformances some 
real pain points will be discovered—and those points *could* be addressed via 
overlapping conformances—but I also suspect that the majority of these pain 
points will also be addressable via some simpler mechanism (a constrained form 
of overlapping, macros, easy wrapper synthesis, etc.).

Thus I’m in favor of banning conditional conformances for now unless doing so 
now would be the same as doing so “forever”, so to speak.

> I have a strong *personal* bias against overlapping conformances, because I 
> feel that the amount of complexity that they introduce into the language and 
> its implementation far outweigh any benefits. Additionally, they enable use 
> cases (e.g., static metaprogramming-ish tricks) that I feel would be actively 
> harmful to the Swift language’s understandability. Generics systems can get 
> very complicated very quickly, so any extension needs to be strongly 
> motivated by use cases to matter to all or most Swift developers.

This is purely anecdotal but I had a lot of utility code laying around that I’d 
marked with notes like `// TODO: revisit once conditional conformances are 
available`.

When I was leaving those notes I was expecting to need overlapping conformances 
often, but I reviewed them *before* replying and I actually haven’t found an 
example where having overlapping conformances is both (1) a significant win and 
also (2) a win in a way that’d be of broad, general interest.

- 80% have no real need for overlapping conditional conformances
- 15% might have “elegance gains” but nothing practically-significant
- 5% would *probably* see real gains but are likely not of broad interest

…which wasn’t what I was expecting, but leaves me a lot more comfortable 
without overlapping conformances for now than I was in the abstract.

> 
>   - Doug
> 
>> 
>>> On Sep 26, 2016, at 7:18 PM, Douglas Gregor via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Conditional conformances
>>> 
>>> Proposal: SE- 
>>> 
>>> Author: Doug Gregor 
>>> Review Manager: TBD
>>> Status: Awaiting review
>>> During the review process, add the following fields as needed:
>>> 
>>> Decision Notes: Rationale 
>>> , Additional Commentary 
>>> 
>>> Bugs: SR- , SR- 
>>> 
>>> Previous Revision: 1 
>>> 
>>> Previous Proposal: SE- 
>>> 
>>>  
>>> Introduction
>>> 
>>> Conditional conformances express the notion that a generic type will 
>>> conform to a particular protocol only when it's type arguments meet certain 
>>> requirements. For example, the Array collection can implement the Equatable 
>>> protocol only when its elements are themselves Equatable, which can be 
>>> expressed via the following conditional conformance on Equatable:
>>> 
>>> extension Array: Equatable where Element: Equatable {
>>>   static func ==(lhs: Array, rhs: Array) -> Bool { ... }
>>> }
>>> This feature is part of the generics manifesto 
>>> 
>>>  because it's something that fits naturally into the generics model and is 
>>> expected to have a high impact on the Swift standard library.

Re: [swift-evolution] associated objects

2016-09-30 Thread Jay Abbott via swift-evolution
Robert,

What it does is allow developers to extend the language to do things that
it doesn't support. Associated Objects is just a flexible way to allow
developers to do that, and that's how I used it in Objective-C, so that's
what I thought of in Swift when I found that "I want to do  but the
language doesn't support it". Maybe there's a completely different way to
achieve the same thing - but I just went with what I know.

I'm not trying to make Swift more like Obj-C - far from it - I want Swift
to ditch all the Obj-C related stuff and be its own thing. It frustrates me
to see bad patterns in UIKit (for example) being present in UIKit-for-Swift
(I understand why of course, but it's annoying still). Also things like the
CharacterSet discussion in the other thread - to me it seems like some of
the Objective-C-related implementation details of Swift libraries are
leaking out (the language itself doesn't seem to suffer from this though).

So it's difficult to come up with concrete examples of "things a developer
might want to do but the language doesn't support" because almost by
definition they are unforeseen. I can only enumerate the things I have
wanted to do in Obj-C and Swift and how I got around it.
- Dynamically add properties to a class (obc-c) / implement stored
properties (swift).
- Add per-instance methods at run-time.
- Perform a function when some other object is deallocated (haven't solved
this in Swift yet, but in obj-c associated object deallocation is
well-defined so I used that).
- Other unforeseen things...

So maybe Associated Objects isn't the answer and I should have stated the
problem better, instead of jumping to what I thought the answer might be...
the problem I want to solve is this:

As a developer I want to do  but the language doesn't support it... what
helpful thing *can* I use right now that allows me to achieve this? I
accept the disclaimer by ticking this box:
[ ] Yes, I understand that I'm not using Swift anymore, but some custom
run-time thing that I'm building myself on top of Swift, so if I want type
safety I have to implement it, if I want copy-on-write or other
optimisations, I have to implement it, and I understand that performance
might not be the best too.

If Swift can provide something to help developers go beyond the abilities
the current version, isn't that a good idea?

On Fri, 30 Sep 2016 at 07:13 Brent Royal-Gordon 
wrote:

> > On Sep 28, 2016, at 9:27 AM, Robert Widmann via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > To make this kind of pattern type safe you would, for example, need to
> keep track metatype pointers too and use the dynamic cast machinery to
> check the type on retrieval.
>
> Actually, a somewhat different (DispatchSpecificKey-style) design makes
> type safety pretty easy:
>
> import Cocoa
>
> let myValue = AssociatedValue(.strong, ofType: String.self, on:
> NSView.self)
>
> let view = NSView()
> myValue[view] = "Hello, world!"
> myValue[view]
>
> Implementation here: <
> https://gist.github.com/brentdax/75bfd619379fea53d8ca8afaa16d95bb>
>
> Nevertheless, I don't think this should be shipped in Swift; associated
> objects are as esoteric as they come.
>
> --
> Brent Royal-Gordon
> Architechies
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Conditional conformances

2016-09-30 Thread Matthew Johnson via swift-evolution

> On Sep 30, 2016, at 1:23 AM, Douglas Gregor  wrote:
> 
> 
>> On Sep 28, 2016, at 4:30 PM, Matthew Johnson > > wrote:
>> 
 Is the decision on "no-overlapping-conformances” something that’s seen-as 
 set in stone permanently, set in stone for the near future, or perhaps at 
 least somewhat open to reconsideration at the present moment?
>>> 
>>> There hasn’t been a decision per se, so it that sense it’s open to 
>>> reconsideration.
>>> 
>>> I have a strong *personal* bias against overlapping conformances, because I 
>>> feel that the amount of complexity that they introduce into the language 
>>> and its implementation far outweigh any benefits.
>> 
>> I would like a bit further clarification on what the prohibition of 
>> overlapping conformances implies.
> 
> I think I presented it poorly in the proposal, and will see if I can find a 
> clearer exposition (for posterity, if not soon enough to aid the review).
> 
>>  For example, consider this modification of your example in a Swift that 
>> allows for same type constraints in extensions.  Would this be allowed?
> 
> Short answer: no. Longer answer below.
> 
>>  There would be two different conformances to Foo for SomeWrapper, but they 
>> would never “overlap” (i.e. both be candidates for the same concrete type).
>> struct SomeWrapper {
>>   let wrapped: Wrapped
>> }
>> 
>> protocol Foo {
>> associatedtype Bar
>>   func bar() -> Bar
>> }
>> 
>> extension SomeWrapper: Foo where Wrapped == String {
>>   func bar() -> String {
>> return “Hello"
>>   }
>> }
>> 
>> extension SomeWrapper: Foo where Wrapped == Int {
>>   func bar() -> Int {
>> return 0
>>   }
>> }
> This is a case where we *could* determine that the two conformances will 
> never overlap, because we can statically determine that trying to satisfy the 
> requirements of both extensions at the same time results in a 
> conflict—Wrapped cannot be both equal to an Int and a String. However, I 
> think it’s a bad idea to allow these two conformances, for a couple of 
> reasons:
> 
> (1) It’s going to immediately feature-creep as developers want to be able to 
> treat more kinds of extensions as non-overlapping, e.g., calling two 
> protocols mutually-exclusive (Russ’s example), or introducing some kind of 
> negative constraint (‘Wrapper: !Foo’) to arbitrarily break overlaps. 

Sure, we probably would see requests like this.  The fundamental issue here IMO 
is that type systems are great until they don’t let you express something that 
is relatively obvious conceptually, such as the above example.  This if ok as 
long as there is an alternative available that isn’t clearly worse (as in more 
boilerplate-y, less expressive, etc) and it is easily assimilated by the 
community using the language.  But it becomes very frustrating when that isn’t 
the case.  I’m not sure how often we will fall into the latter bucket because 
of this restriction but it seems likely to happen from time to time.

> (2) The issues I mentioned to Russ about the type checker having to treat 
> these as disjunctions, which can lead us into yet more exponential behavior.

Does Dave’s idea of not treating SomeWrapper itself as a type help at all here? 
 That is how I also conceptualize things.  SomeWrapper is a “type constructor” 
and SomeWrapper is a type.

> (3) I don’t think it’s good design; if you’re going to write an extension to 
> make type X conform to protocol P, you should do so in the most general way 
> that is reasonable for X and P—not pick the one-off case you need this 
> moment. This way, when you do hit two ways in which X conforms to P, the 
> compile complains and nudges you to factor the conformance into something 
> more reusable and non-overlapping.

I agree with this in principle.  However, sometimes a more performant 
implementation might be possible with more type information (as discussed 
below).  It may also be the case that sometimes the general implementation is 
more difficult to write than is worth it for the current application.

> 
> 
>> Secondarily, I understand the reason for letting the “least specific” 
>> candidate conformance win (it is the most general).  But I wonder if this 
>> might leave performance on the table in some cases where a more specific 
>> implementation could use knowledge of the more specific details to implement 
>> the members more efficiently.  Using the example in your proposal, what if 
>> knowing `T` conforms to `S`, not just `R` allows `X5` to provide a more 
>> efficient implementation of the members of `P` and `R`?  If so, it seems 
>> unfortunate to leave that performance on the table.  Is this a valid 
>> concern?  Or is it unlikely to come up often enough in practice to matter?
> 
> It’s a valid concern, and I’m sure it does come up in practice. Let’s create 
> a small, self-contained example:
> 
> protocol P {
>   func f()
> }
> 
> protocol Q: P { }
> 
> struct X { let t: T}
> 
> extension X: P where T: P 

Re: [swift-evolution] [swift-evolution-announce] [Review] SE-0143: Conditional Conformances

2016-09-30 Thread Matthew Johnson via swift-evolution

> What is your evaluation of the proposal?
Huge +1.  Conditional conformances are at the very top of the list of 
frustrating limitations in Swift.  Lifting that limitation can’t happen soon 
enough for me.

I have some concern that the restriction on overlapping conformances could 
continue to cause occasional frustration at times.  However, I don’t have a 
solid basis for that concern in the sense of specific use cases.  Doug also 
raises very good points about the complexity they introduce.  

I would like to see the specific details and restrictions discussed in more 
detail and possibly revised following that discussion.  I trust the core team 
to make the right decision.  If, after in-depth discussion, the core team 
decides to accept the proposal as-is I support that.  Conditional conformances 
are a huge step forward.  We will gain a tremendously important facility with 
them even if pain points still remain.  That said, I do hope we will have 
options for addressing pain points that arise down the road.

I would also like to see serious consideration given to the performance 
implications of choosing the “least specialized” (but most general) 
conformance.  As noted in the discussion, this seems like it could be a 
slippery slope to sub-optimal performance.  My hope for Swift is that generic 
code will achieve performance as close to the “zero cost abstraction” principle 
in the C++ community (especially if / when we have a Rust-like ownership system 
that allows us to avoid reference counting).
> Is the problem being addressed significant enough to warrant a change to 
> Swift?
Yes.  It is one of the most significant problems with the current state of the 
language.
> Does this proposal fit well with the feel and direction of Swift?
Yes.
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
I am extremely familiar with the limitations of the current model having bumped 
up against them continuously.  I have given this specific proposal 
consideration somewhere between a quick read and an in-depth study.  I have 
been following the discussion in-depth and have read everyone’s comments 
carefully.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] associated objects

2016-09-30 Thread Robert Widmann via swift-evolution

> On Sep 30, 2016, at 9:40 AM, Jay Abbott  wrote:
> 
> Robert,
> 
> What it does is allow developers to extend the language to do things that it 
> doesn't support. Associated Objects is just a flexible way to allow 
> developers to do that, and that's how I used it in Objective-C, so that's 
> what I thought of in Swift when I found that "I want to do  but the 
> language doesn't support it". Maybe there's a completely different way to 
> achieve the same thing - but I just went with what I know.

"I want to do  but the language doesn't support it” is the whole reason for 
this list!  I want to know what “” is in order to wrap my head around your 
proposal better.  I’m not here to invalidate your work with a slew of 
criticisms, I’m just trying to understand your proposal by probing you about it.


> So it's difficult to come up with concrete examples of "things a developer 
> might want to do but the language doesn't support" because almost by 
> definition they are unforeseen. I can only enumerate the things I have wanted 
> to do in Obj-C and Swift and how I got around it.
> - Dynamically add properties to a class (obc-c) / implement stored properties 
> (swift).
> - Add per-instance methods at run-time.
> - Perform a function when some other object is deallocated (haven't solved 
> this in Swift yet, but in obj-c associated object deallocation is 
> well-defined so I used that).
> - Other unforeseen things…

Again, these are features and I want motivations behind them.  Why should you 
be able to dynamically add stored properties and methods to any Swift class?  
Why should you be able to observe deallocation if deallocation calls are not 
guaranteed (remember, Objective-C and Swift do not guarantee -dealloc/deinit 
calls in any order at any time - please don’t assume an RAII-like model because 
it will lead to memory leaks and malformed code).

I will say: Perhaps if you’re having trouble motivating the inclusion of this 
feature, you may want to step back and reevaluate its place in the language and 
why you wanted to write this library in the first place.  Often times, I find 
that really helps get the creative juices flowing.  Or, if I can’t come up with 
anything, it means I go back to step 1 and start over.  Proposals can be as 
much a learning process for us as it is for you.

> 
> So maybe Associated Objects isn't the answer and I should have stated the 
> problem better, instead of jumping to what I thought the answer might be... 
> the problem I want to solve is this:
> 
> As a developer I want to do  but the language doesn't support it... what 
> helpful thing *can* I use right now that allows me to achieve this? I accept 
> the disclaimer by ticking this box:
> [ ] Yes, I understand that I'm not using Swift anymore, but some custom 
> run-time thing that I'm building myself on top of Swift, so if I want type 
> safety I have to implement it, if I want copy-on-write or other 
> optimisations, I have to implement it, and I understand that performance 
> might not be the best too.
> 

So from what I’ve gathered you’ve written a library to do this yourself.  You 
have a vision for how you want to use this library.  You think that vision is 
compatible with a language-level change.  From my perspective, your job now is 
to articulate that vision and motivate it to this list.  I don’t think 
associated objects and the other dynamic features you mention are fundamentally 
incompatible with Swift, I just think the design that I’ve seen so far may not 
be the best way of going about it and I’m voicing my concerns as much.  

> If Swift can provide something to help developers go beyond the abilities the 
> current version, isn't that a good idea?

No one disputes this.  We just want to see your rationale.

> 
> On Fri, 30 Sep 2016 at 07:13 Brent Royal-Gordon  > wrote:
> > On Sep 28, 2016, at 9:27 AM, Robert Widmann via swift-evolution 
> > mailto:swift-evolution@swift.org>> wrote:
> >
> > To make this kind of pattern type safe you would, for example, need to keep 
> > track metatype pointers too and use the dynamic cast machinery to check the 
> > type on retrieval.
> 
> Actually, a somewhat different (DispatchSpecificKey-style) design makes type 
> safety pretty easy:
> 
> import Cocoa
> 
> let myValue = AssociatedValue(.strong, ofType: String.self, on: 
> NSView.self)
> 
> let view = NSView()
> myValue[view] = "Hello, world!"
> myValue[view]
> 
> Implementation here: 
>  >
> 
> Nevertheless, I don't think this should be shipped in Swift; associated 
> objects are as esoteric as they come.
> 
> --
> Brent Royal-Gordon
> Architechies
> 

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

Re: [swift-evolution] associated objects

2016-09-30 Thread Jay Abbott via swift-evolution
On Fri, 30 Sep 2016 at 15:41 Robert Widmann 
wrote:

> "I want to do  but the language doesn't support it” is the whole reason
> for this list!  I want to know what “” is in order to wrap my head
> around your proposal better.  I’m not here to invalidate your work with a
> slew of criticisms, I’m just trying to understand your proposal by probing
> you about it.
>

I know, and appreciate this, thanks :) I'm not easily offended and I prefer
to be wrong in a room full of smarter people than right (or think that I'm
right when maybe not) in a room full of not smarter people. But I do
struggle to articulate this without patronising everyone by explaining how
I think it is (in order to be corrected) all the time. Hope that even makes
sense!


> Again, these are features and I want motivations behind them.  *Why*
> should you be able to dynamically add stored properties and methods to
> *any* Swift class?
>

If I'm using an existing framework such as UIKit, and I want to add
something it doesn't support, like drag+drop to all UIViews for example,
then my implementation might want to use stored properties to help keep
track of drag+drop-related config and state (isDraggable, isDropTarget,
sourceView, etc.). This way I can extend UIView and use the stored
properties from my extension methods, while keeping all the functionality
of all its subclasses.

There's probably a much better way to express the above in the abstract -
sorry I suck at that :)

*Why* should you be able to observe deallocation if deallocation calls are
> not guaranteed (remember, Objective-C and Swift do not guarantee
> -dealloc/deinit calls in any order at any time - please don’t assume an
> RAII-like model because it will lead to memory leaks and malformed code).
>

It's not deallocation, but deinit that would be useful. My motivation in
Swift for wanting this was to get around lazy weak reference zeroing in my
associated objects implementation. If the object is deinited, you can't ask
it for an associated object, therefore its weak reference in my
implementation would never be accessed so it would hang around forever. I
got around that with a horrible clean-up hack that accesses the weak
references just to ensure they get zeroed, so I wanted non-lazy zeroing (or
a deinit hook).

I will say: Perhaps if you’re having trouble motivating the inclusion of
> this feature, you may want to step back and reevaluate its place in the
> language and why you wanted to write this library in the first place.
> Often times, I find that really helps get the creative juices flowing.  Or,
> if I can’t come up with anything, it means I go back to step 1 and start
> over.  Proposals can be as much a learning process for us as it is for you.
>

I know exactly why I wanted associated objects - to implement a) stored
properties in extensions; and b) per-instance actions. If stored properties
were available in extensions then I would not need it at all: a) I would
already have it; b) I'd implement it using stored properties.

So from what I’ve gathered you’ve written a library to do this yourself.
> You have a vision for how you want to use this library.  You think that
> vision is compatible with a language-level change.  From my perspective,
> your job now is to articulate that vision and motivate it to this list.  I
> don’t think associated objects and the other dynamic features you mention
> are fundamentally incompatible with Swift, I just think the design that
> I’ve seen so far may not be the best way of going about it and I’m voicing
> my concerns as much.
>

I guess you're right - it's really stored properties in extensions that I
want...  but actually - what's the difference? Aren't they basically the
same thing? :)

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


Re: [swift-evolution] class/struct inner member access scope classifier

2016-09-30 Thread Ted F.A. van Gaalen via swift-evolution
Hi Jeremy and Nevin

Sorry for the delay. quite busy.

As described, the point of my message is that I would like to have the inner 
members of a class
as default private, that is, not visible in the outer scope and to reveal 
members (entities)
of the class to the outside world *explicitly* by specifying an access 
qualifier like
“public” or “internal”, so exactly the other way round as it is now. 
In the current situation I have to precede all declarations which I don’t want 
to reveal
with “private”. Usually most entities of a class should not be visible outside 
of it. 
To prevent source breaking one could precede the class definition with a 
keyword, telling
Swift that all members of a class are private by default like so

closedscope class TG3DGauge: SCNNode
{

var needles = [SCNNode]()  // is now private by default
var fmtStr = “"// is now private by default

public var value: CGFloat = 0 // Public!! visible outside class also for 
“fileprivate" or “internal”  

(as written before)  

If this “closedscope” qualifier is not used things are exactly as it is now.

The “fileprivate” qualifier doen’t need to go so no source breaking here.
I simply stated that I am not really a fan of it.

Kind Regards
Ted



> On 27 Sep 2016, at 10:34, Jeremy Pereira  
> wrote:
> 
> 
>> On 26 Sep 2016, at 20:58, Ted F.A. van Gaalen via swift-evolution 
>>  wrote:
>> 
>> Hello! Hope you are all OK! 
>> 
>> 
>> As far as I can see without binoculars, the “fileprivate” acces modifier
>> could be dropped, were it not for source compatibility reasons... 
>> 
>> Unless I am missing something: 
> 
> Yes you are missing something. I, for example have a few cases where it is 
> useful. On the other hand, I was against the change in the meaning of private 
> but, I have to concede that the new meaning is useful. 
> 
> As for dropping file private, why? You don’t have to use it if you don’t want 
> to, so it’s not hurting you. On the other hand, I can use it when I deem it 
> to be the right thing to do. 
> 
> 
>> I don’t want the inner elements
>> of a class (or struct ?) to be visible in outer scope!
>> This is the default case in most OOP languages. 
> 
> The default in Java is package scope. I’m not sure what the default in C++ 
> is, but it’s not private, ditto Javascript. So while that might not be most 
> OOP languages, it probably covers most OOP programs.
> 
> While I think private by default has merit, we are where we are.
> 
> 

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


Re: [swift-evolution] [Review] SE-0143: Conditional Conformances

2016-09-30 Thread Douglas Gregor via swift-evolution

> On Sep 29, 2016, at 10:16 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> Obviously I'm a huge +1 for this feature, but I have some concerns and
> questions about the particulars.
> 
> on Wed Sep 28 2016, Joe Groff  wrote:
> 
>> Conditional conformances also have a run-time aspect, because a
>> dynamic check for a protocol conformance might rely on the evaluation
>> of the extra requirements needed to successfully use a conditional
>> conformance. For example:
>> 
>> ```swift
>> protocol P {
>>  func doSomething()
>> }
>> 
>> struct S: P {
>>  func doSomething() { print("S") }
>> }
>> 
>> // Array conforms to P if it's element type conforms to P
>> extension Array: P where Element: P {
>>  func doSomething() {
>>for value in self {
>>  value.doSomething()
>>}
>>  }
>> }
>> 
>> // Dynamically query and use conformance to P.
>> func doSomethingIfP(_ value: Any) {
>>  if let p = value as? P {
>>p.doSomething()
>>  } else {
>>print("Not a P")
>>  }
>> }
>> 
>> doSomethingIfP([S(), S(), S()]) // prints "S" three times
>> doSomethingIfP([1, 2, 3])   // prints "Not a P"
>> ```
>> 
>> The `if-let` in `doSomethingIfP(_:)` dynamically queries whether the
>> type stored in `value` conforms to the protocol `P`. In the case of an
>> `Array`, that conformance is conditional, which requires another
>> dynamic lookup to determine whether the element type conforms to `P`:
>> in the first call to `doSomethingIfP(_:)`, the lookup finds the
>> conformance of `S` to `P`. In the second case, there is no conformance
>> of `Int` to `P`, so the conditional conformance cannot be used. The
>> desire for this dynamic behavior motivates some of the design
>> decisions in this proposal.
> 
> Whether a dynamic evaluation is required at this point seems to depend
> on how you represent conformance.  Saying “Array conforms conditionally”
> treats Array as a type, but it might be simpler to treat Array as a
> family of concrete types.

This is already the case in the runtime; we specialize the metadata for generic 
types.

>  I always envisined it this way: at the moment
> a module using the concrete type Array comes together with an
> extension (either in that module or in another) that makes Array
> conform to Equatable depending on properties of T, that extension is
> evaluated and Array is marked as conforming or not.

If the protocol, Array, and Foo all come from different modules, this process 
happens at runtime. Yes, the optimizer could specialize the conformance at 
compile time in many common cases, but you can’t see every possible 
specialization without whole-program analysis, so it doesn’t change the model.


>  Then asking
> about a type's conformance is always a simple thing.  But I suppose
> which approach wins is dependent on many factors, and the other way can
> be thought of as adding lazy evaluation to the basic model, so if this
> adds nothing to your thinking please excuse the static.

Without whole-program information, you need to have the runtime capability (or 
disallow the use of this feature in runtime queries). Static specialization can 
be considered an optimization to this model.

>> Note that, for an arbitrary type `T`, there are four potential answers to
>> the question of whether `SomeWrapper` conforms to `Equatable`:
>> 
>> 1. No, it does not conform because `T` is neither `Equatable` nor
>> `HasIdentity`.
>> 2. Yes, it conforms via the first extension of `SomeWrapper` because
>> `T` conforms to `Equatable`.
>> 3. Yes, it conforms via the second extension of `SomeWrapper` because
>> `T` conforms to `HasIdentity`.
>> 4. Ambiguity, because `T` conforms to both `Equatable` and
>> `HasIdentity`.
> 
> Arguably in this case you could say yes it conforms and it doesn't
> matter which extension you use because there's only one sensible
> semantics for Equatable.

Sure, we know the semantics of these protocols: === should imply ==.

>  Other protocols are less obvious, though
> (c.f. Int's conformance to Monoid with +/0 vs */1).

Right.

>> 2. It is no longer possible to uniquely say what is required to make a
>> generic type conform to a protocol, because there might be several
>> unrelated possibilities. This makes reasoning about the whole system
>> more complex, because it admits divergent interfaces for the same
>> generic type based on their type arguments. 
> 
> I'm pretty sure we already have that.  Array would have hashValue if
> T were hashable, and < if T were comparable, and never the twain shall
> meet.

The first sentence of (2) meant “to a *given* protocol”, not just “to any 
protocol." But, yes, you’re right that (e.g.) overloading across 
differently-constrained extensions and protocol extensions means dealing with 
divergent interfaces… and it’s been a problem for type checker and humans both.

> 
>> At its extreme, this invites the kind of cleverness we've seen in the
>> C++ community with template metaprogramming, which is something Swift
>> has sought to avoi

Re: [swift-evolution] [Proposal draft] Conditional conformances

2016-09-30 Thread Douglas Gregor via swift-evolution

> On Sep 30, 2016, at 6:25 AM, plx via swift-evolution 
>  wrote:
> 
> 
>> On Sep 28, 2016, at 5:53 PM, Douglas Gregor > > wrote:
>> 
>> 
>>> On Sep 28, 2016, at 1:28 PM, plx via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> It’s good to see this starting to happen!
>>> 
>>> Is the decision on "no-overlapping-conformances” something that’s seen-as 
>>> set in stone permanently, set in stone for the near future, or perhaps at 
>>> least somewhat open to reconsideration at the present moment?
>> 
>> There hasn’t been a decision per se, so it that sense it’s open to 
>> reconsideration.
> 
> I see. A related question: if overlapping conditional conformances are 
> disallowed in Swift 4, would e.g. ABI concerns make it infeasible to relax 
> that restriction in future Swift (5, 6, X, etc.)?

It’s hard to be definitive without having a specific design for what 
overlapping conditional conformances would mean, but I feel fairly confident 
that we could introduce them later in some form. It would almost certainly 
involve deployment limitations—one would not be able to dynamically query for 
an overlapping conformance and have that code run correctly on a Swift 4 
runtime—but the general scheme in the ABI should generalize. 

> 
>> I have a strong *personal* bias against overlapping conformances, because I 
>> feel that the amount of complexity that they introduce into the language and 
>> its implementation far outweigh any benefits. Additionally, they enable use 
>> cases (e.g., static metaprogramming-ish tricks) that I feel would be 
>> actively harmful to the Swift language’s understandability. Generics systems 
>> can get very complicated very quickly, so any extension needs to be strongly 
>> motivated by use cases to matter to all or most Swift developers.
> 
> This is purely anecdotal but I had a lot of utility code laying around that 
> I’d marked with notes like `// TODO: revisit once conditional conformances 
> are available`.
> 
> When I was leaving those notes I was expecting to need overlapping 
> conformances often, but I reviewed them *before* replying and I actually 
> haven’t found an example where having overlapping conformances is both (1) a 
> significant win and also (2) a win in a way that’d be of broad, general 
> interest.
> 
> - 80% have no real need for overlapping conditional conformances
> - 15% might have “elegance gains” but nothing practically-significant
> - 5% would *probably* see real gains but are likely not of broad interest
> 
> …which wasn’t what I was expecting, but leaves me a lot more comfortable 
> without overlapping conformances for now than I was in the abstract.

Very interesting, thanks for doing this review!

- Doug

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


Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Adrian Zubarev via swift-evolution
About the proposed names:

To be crystal clear we could use more descriptive names for our two types. 
Today T.Type is referred as *metatype* and serving two different purposes at 
once.

It’s a concrete type; we call it Type or other suggested names looked like 
ExactType, StaticType etc.

T.Type is also the base type for all subtypes of T.

Protocols has one exception here.

1.1. The concrete type for protocols is not T.Type but T.Protocol.

2.1. T.Protocol has only one supertype, which is the existential (#2) Any.Type 
type.

Our proposal slices this behaviour into two different types, where you only can 
create a *concrete type* Type with T.self or shadow a concrete type behind 
Subtype with subtype(of:) function.

To be precise the correct names should be:

Metatype for the concrete type (#1).
ExistentialMetatype for the existential type (#2).
But we felt that we should adopt the existing name from T.Type and use the 
short form for the *concrete type* Type.

Brent already showed in multiple examples but the question seems to come up 
over and over about the correct name of the current type(of:) function.

Imagine this scenario:

protocol P {}
struct A : P {}

let proto: P = A()
let any: Any = proto

// the old behaviour looked like this

// *concrete* `A.Type` is hidden behind the existential `Any.Type`
let anyMetatype: Any.Type = any.dynamicType  

anyMetatype is P.Type //=> true `P.Type` is the existential type here
anyMetatype is A.Type //=> true
let aMetatype = anyMetatype as! A.Type // Okay

// today `type(of:)` does the same trick

// After this proposal:
// subtype(of instance: T) -> Subtype

// The function will extract `Type` for `any` but shadow it behind 
`Subtype`
let anyMetatype: `Subtype` = subtype(of: any)

// The correct relationship look like this:
// Subtype : Subtype
// Subtype : Subtype
// Type : Subtype

anyMetatype is Subtype //=> true
anyMetatype is Subtype //=> true
anyMetatype is Type//=> true
anyMetatype is Type//=> false
anyMetatype is Type  //=> false
let aMetatype_1 = anyMetatype as! Subtype // Okay
let aMetatype_2 = anyMetatype as! Type// Okay
subtype(of:) function extracts the *concrete type* from the given instance but 
shadows it behind the *existential type* equal to the type of the given 
instance.

subtype(of: T) returns a existential metatype instance Subtype where in 
reality it’s a concrete metatype Type with the relationship like U : T.

This is exact the same behaviour as the old .dynamicType had.

I hope that cleared some raising questions.



-- 
Adrian Zubarev
Sent with Airmail

Am 30. September 2016 um 09:00:53, Goffredo Marocchi via swift-evolution 
(swift-evolution@swift.org) schrieb:

Calling it SuperTypeOf and SubTypeOf would make it less confusing as that 
is how I read it in my mind in your last example.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Xiaodi Wu via swift-evolution
Sorry, my question at least has nothing to do with bikeshedding. I'm
confused about why the proposal feels it's necessary to have both Type and
Subtype. I don't understand Brent's two reasons and was hoping for some
elaboration. I've tried to clarify my question in a gist:

https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167


On Fri, Sep 30, 2016 at 2:09 PM, Adrian Zubarev via swift-evolution <
swift-evolution@swift.org> wrote:

> About the proposed names:
>
> To be crystal clear we could use more descriptive names for our two types.
> Today T.Type is referred as *metatype* and serving two different purposes
> at once.
>
>1.
>
>It’s a concrete type; we call it Type or other suggested names
>looked like ExactType, StaticType etc.
>2.
>
>T.Type is also the *base type* for all subtypes of T.
>
> Protocols has one exception here.
>
> 1.1. The concrete type for protocols is not T.Type but T.Protocol.
>
> 2.1. T.Protocol has only one supertype, which is the existential (#2)
> Any.Type type.
>
> Our proposal slices this behaviour into two different types, where you
> only can create a *concrete type* Type with T.self or shadow a
> concrete type behind Subtype with subtype(of:) function.
>
> To be precise the correct names should be:
>
>- Metatype for the concrete type (#1).
>- ExistentialMetatype for the existential type (#2).
>
> But we felt that we should adopt the existing name from T.Type and use
> the short form for the *concrete type* Type.
> --
>
> Brent already showed in multiple examples but the question seems to come
> up over and over about the correct name of the current type(of:) function.
>
> Imagine this scenario:
>
> protocol P {}
> struct A : P {}
>
> let proto: P = A()
> let any: Any = proto
>
> // the old behaviour looked like this
>
> // *concrete* `A.Type` is hidden behind the existential `Any.Type`
> let anyMetatype: Any.Type = any.dynamicType
>
> anyMetatype is P.Type //=> true `P.Type` is the existential type here
> anyMetatype is A.Type //=> true
> let aMetatype = anyMetatype as! A.Type // Okay
>
> // today `type(of:)` does the same trick
>
> // After this proposal:
> // subtype(of instance: T) -> Subtype
>
> // The function will extract `Type` for `any` but shadow it behind 
> `Subtype`
> let anyMetatype: `Subtype` = subtype(of: any)
>
> // The correct relationship look like this:
> // Subtype : Subtype
> // Subtype : Subtype
> // Type : Subtype
>
> anyMetatype is Subtype //=> true
> anyMetatype is Subtype //=> true
> anyMetatype is Type//=> true
> anyMetatype is Type//=> false
> anyMetatype is Type  //=> false
> let aMetatype_1 = anyMetatype as! Subtype // Okay
> let aMetatype_2 = anyMetatype as! Type// Okay
>
> subtype(of:) function extracts the *concrete type* from the given
> instance but shadows it behind the *existential type* equal to the type of
> the given instance.
>
> subtype(of: T) returns a existential metatype instance Subtype where
> in reality it’s a concrete metatype Type with the relationship like U
> : T.
>
> This is exact the same behaviour as the old .dynamicType had.
>
> I hope that cleared some raising questions.
>
>
>
> --
> Adrian Zubarev
> Sent with Airmail
>
> Am 30. September 2016 um 09:00:53, Goffredo Marocchi via swift-evolution (
> swift-evolution@swift.org) schrieb:
>
> Calling it SuperTypeOf and SubTypeOf would make it less confusing as
> that is how I read it in my mind in your last example.
>
>
> ___
> 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-0143: Conditional Conformances

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

on Fri Sep 30 2016, Douglas Gregor  wrote:

>> On Sep 29, 2016, at 10:16 PM, Dave Abrahams via swift-evolution 
>>  wrote:
>> 
>> 
>> Obviously I'm a huge +1 for this feature, but I have some concerns and
>> questions about the particulars.
>
>> 
>> on Wed Sep 28 2016, Joe Groff  wrote:
>> 
>>> Conditional conformances also have a run-time aspect, because a
>>> dynamic check for a protocol conformance might rely on the evaluation
>>> of the extra requirements needed to successfully use a conditional
>>> conformance. For example:
>>> 
>>> ```swift
>>> protocol P {
>>>  func doSomething()
>>> }
>>> 
>>> struct S: P {
>>>  func doSomething() { print("S") }
>>> }
>>> 
>>> // Array conforms to P if it's element type conforms to P
>>> extension Array: P where Element: P {
>>>  func doSomething() {
>>>for value in self {
>>>  value.doSomething()
>>>}
>>>  }
>>> }
>>> 
>>> // Dynamically query and use conformance to P.
>>> func doSomethingIfP(_ value: Any) {
>>>  if let p = value as? P {
>>>p.doSomething()
>>>  } else {
>>>print("Not a P")
>>>  }
>>> }
>>> 
>>> doSomethingIfP([S(), S(), S()]) // prints "S" three times
>>> doSomethingIfP([1, 2, 3])   // prints "Not a P"
>>> ```
>>> 
>>> The `if-let` in `doSomethingIfP(_:)` dynamically queries whether the
>>> type stored in `value` conforms to the protocol `P`. In the case of an
>>> `Array`, that conformance is conditional, which requires another
>>> dynamic lookup to determine whether the element type conforms to `P`:
>>> in the first call to `doSomethingIfP(_:)`, the lookup finds the
>>> conformance of `S` to `P`. In the second case, there is no conformance
>>> of `Int` to `P`, so the conditional conformance cannot be used. The
>>> desire for this dynamic behavior motivates some of the design
>>> decisions in this proposal.
>> 
>> Whether a dynamic evaluation is required at this point seems to depend
>> on how you represent conformance.  Saying “Array conforms conditionally”
>> treats Array as a type, but it might be simpler to treat Array as a
>> family of concrete types.
>
> This is already the case in the runtime; we specialize the metadata for 
> generic types.
>
>>  I always envisined it this way: at the moment
>> a module using the concrete type Array comes together with an
>> extension (either in that module or in another) that makes Array
>> conform to Equatable depending on properties of T, that extension is
>> evaluated and Array is marked as conforming or not.
>
> If the protocol, Array, and Foo all come from different modules, this
> process happens at runtime. Yes, the optimizer could specialize the
> conformance at compile time in many common cases, but you can’t see
> every possible specialization without whole-program analysis, so it
> doesn’t change the model.
>
>>  Then asking
>> about a type's conformance is always a simple thing.  But I suppose
>> which approach wins is dependent on many factors, and the other way can
>> be thought of as adding lazy evaluation to the basic model, so if this
>> adds nothing to your thinking please excuse the static.
>
> Without whole-program information, you need to have the runtime
> capability (or disallow the use of this feature in runtime
> queries). Static specialization can be considered an optimization to
> this model.

I know it has to happen at runtime in the worst case.  I was suggesting
it could happen at load time rather than as a complication of the
dynamic cast machinery.  In principle all the load-time information can
be usefully cached on-disk.

>>> Note that, for an arbitrary type `T`, there are four potential answers to
>>> the question of whether `SomeWrapper` conforms to `Equatable`:
>>> 
>>> 1. No, it does not conform because `T` is neither `Equatable` nor
>>> `HasIdentity`.
>>> 2. Yes, it conforms via the first extension of `SomeWrapper` because
>>> `T` conforms to `Equatable`.
>>> 3. Yes, it conforms via the second extension of `SomeWrapper` because
>>> `T` conforms to `HasIdentity`.
>>> 4. Ambiguity, because `T` conforms to both `Equatable` and
>>> `HasIdentity`.
>> 
>> Arguably in this case you could say yes it conforms and it doesn't
>> matter which extension you use because there's only one sensible
>> semantics for Equatable.
>
> Sure, we know the semantics of these protocols: === should imply ==.
>
>>  Other protocols are less obvious, though
>> (c.f. Int's conformance to Monoid with +/0 vs */1).
>
> Right.
>
>>> 2. It is no longer possible to uniquely say what is required to make a
>>> generic type conform to a protocol, because there might be several
>>> unrelated possibilities. This makes reasoning about the whole system
>>> more complex, because it admits divergent interfaces for the same
>>> generic type based on their type arguments. 
>> 
>> I'm pretty sure we already have that.  Array would have hashValue if
>> T were hashable, and < if T were comparable, and never the twain shall
>> meet.
>
> The first sentence of (2) meant “to a *given* protocol”, no

Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Anton Zhilin via swift-evolution
2016-09-30 22:48 GMT+03:00 Xiaodi Wu via swift-evolution <
swift-evolution@swift.org>:

Sorry, my question at least has nothing to do with bikeshedding. I'm
> confused about why the proposal feels it's necessary to have both Type and
> Subtype. I don't understand Brent's two reasons and was hoping for some
> elaboration. I've tried to clarify my question in a gist:
>
> https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167
>
Regardless of syntax, there are Metatype and ExistentialMetatype
“under the hood”. I’ll take the liberty to use these names for this post.

Purpose and difference between the two kinds of metatypes is easy to
understand. If it helps, size of Metatype is typically 0 while size of
ExistentialMetatype is typically 8.

NOTE: Metatype can’t be a subtype of ExistentialMetatype for
protocols P, because protocols do not implement their own static
requirements.

Apparently, creators of Swift also thought that two kinds of metatypes are
too difficult for an average developer. So an attempt was made to unify
both under a single name, T.Type. For “final” types like structs, T.Type
maps onto Metatype. For classes and protocols, T.Type maps onto
ExistentialMetatype.

This abstraction turned out to be leaky. I’ll give 3 leaks.

   1. Because of Note, we could not have ID of a protocol itself inside of
   any kind of metatype. This feature was needed in real code. The solution
   was to add T.Protocol syntax that could only be used for protocols to
   create a Metatype. But this solution created a plethora of other
   inconsistencies and abstraction leaks (which were explored by Adrian).
   Arguably the most important is (2).
   2. In generic functions accepting T.Type, passing T.self creates an
   instance of T.Protocol, which is still described in code as T.Type.
   *boom!*
   3. Accepting static metatypes in functions is often what people want.
   Consider the following basic example:

func create(type: T.Type)

Most probably, create does not read contents of type to deal with
appropriate subtype. It does not support existentiality, type is here for
function specialization. But in case T is subtypable, we still pass around
those 8 bytes that are not used by the create, confusing both compiler and
some developers. In 90% cases, when we see such a function, it throws off
value of metatype instance.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Adrian Zubarev via swift-evolution
I replied on your gist directly, but you can also read my reply below.

I though I made it crystal clear in my last post what the main problem is.

Again:

T.Type serves two jobs at once.

It’s a concrete metatype of T.
It’s an existential metatype of T where other metatypes where U is a subtype of 
T (U : T) are subtypes of this existential metatype.
Forget about protocols for a moment:

struct S { }  

let metatype_1: Any.Type = S.self // <~~ (concrete) metatype
//  ^ existential metatype

let metatype_s: S.Type = S.self // <~~ (concrete) metatype
//  ^ existential metatype

/*
   The relationship looks here like this

   (concrete metatype) `T.Type : T.Type` (existential metatype)  

   OR for the given example: `S.Type : S.Type : Any.Type` (last one is again an 
existential metatype)
   This looks confusing right?
*/

class B { }
class D : B { }

let metatype_b: B.Type = B.self // <~~ (concrete) metatype
//  ^ existential metatype

metatype_b is D.Type // false

let metatype_d: D.Type = D.self // <~~ (concrete) metatype
//  ^ existential metatype

let metatype_2: B.Type = metatype_d   // Totally fine
let metatype_3: Any.Type = metatype_2 // Okay

metatype_3 is D.Type // true

/*
   Relationship:

   (existential metatype) `B.Type : Any.Type` (existential metatype)
   (concrete metatype) `B.Type : B.Type` (existential metatype)

   (existential metatype) `D.Type : B.Type` (existential metatype)
   (concrete metatype) `D.Type : D.Type` (existential metatype)
*/
It should be clear by now that there is this odd T.Type : T.Type relationship. 
We want to correct this behaviour + solve the problem that raises with 
protocols with one simple and single design.

Let’s see what happens with protocols:

protocol P { }  

let metatype_p: P.Type = P.self // Error, because the concrete metatype is not 
a subtype of the existential metatype of P

// Furthermore `P.self` is `P.Protocol`

let metatype_3: Any.Type = P.self // fine <~~ (concrete) metatype
//  ^ existential metatype

/*
   Relationship:
   (concrete metatype) `P.Protocol : Any.Type` (existential metatype)
   (existential metatype) `P.Type : Any.Type` (existential metatype)

   At this time `P.Type : Any.Type` is an existential metatype that exists but 
it does not have any subtypes!
*/

struct I : P { }

let metatype_i: I.Type = I.self // <~~ (concrete) metatype
//  ^ existential metatype

let metatype_4: P.Type = metatype_i // fine
//  ^ existential metatype

metatype_4 is I.Type // true

/*
   Relationship:
   (existential metatype) `P.Type : Any.Type` (existential metatype)
   (existential metatype) `I.Type : P.Type` (existential metatype)
   (concrete metatype) `I.Type : I.Type` (existential metatype)
*/
There is a huge overlap in the current design. I hope this cleared your 
question here.

Side note: The following function isn’t possible to implement with the current 
T.Type design because in generic context a protocol will end up T.Protocol.

func dynamic(subtype: Subtype, `is` _: Type) -> Bool {
  return type is Subtype
}
The proposed design however solves these problems and the relationship becomes 
clearer:

(existential metatype) `Subtype : Subtype` (existential metatype)
(concrete metatype) `Type : Subtype` (existential metatype)

(existential metatype) `Subtype : Subtype` (existential metatype)
(concrete metatype) `Type : Subtype` (existential metatype)

(existential metatype) `Subtype : Subtype` (existential metatype)
(concrete metatype) `Type : Subtype` (existential metatype)

(existential metatype) `Subtype : Subtype` (existential metatype)
(existential metatype) `Subtype : Subtype` (existential metatype)
(concrete metatype) `Type : Subtype` (existential metatype)
The only way to work with Subtype is by using subtype(of:) function of by 
manually shadowing a concrete metatype Type.

The only way to instantiate a concrete metatype is done with T.self.



-- 
Adrian Zubarev
Sent with Airmail

Am 30. September 2016 um 21:48:39, Xiaodi Wu (xiaodi...@gmail.com) schrieb:

Sorry, my question at least has nothing to do with bikeshedding. I'm confused 
about why the proposal feels it's necessary to have both Type and Subtype. I 
don't understand Brent's two reasons and was hoping for some elaboration. I've 
tried to clarify my question in a gist:

https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167


On Fri, Sep 30, 2016 at 2:09 PM, Adrian Zubarev via swift-evolution 
 wrote:
About the proposed names:

To be crystal clear we could use more descriptive names for our two types. 
Today T.Type is referred as *metatype* and serving two different purposes at 
once.

It’s a concrete type; we call it Type or other suggested names looked like 
ExactType, StaticType etc.

T.Type is also the base type for all subtypes of T.

Protocols has one exception here.

1.1. The concrete type for protocols is not T.Type but T.Protocol.

2.1. T.Protocol ha

Re: [swift-evolution] associated objects

2016-09-30 Thread Ted F.A. van Gaalen via swift-evolution

> What it does is allow developers to extend the language to do things that it 
> doesn't support. 


Hitting boundaries... or so it seems... This is very interesting. 
In spite of its very modern approach, wether we like it or not, Swift is 
still a conventional Hard Coded Statical Programming Language,
 (here further in this text referred to as HCSPL) 
which means that, like in C++ or C# etc. its language 
elements are essentially predefined, "fixed", and that 
it is therefore a daunting task to make the language as 
versatile as possible and to satisfy everyone's requirements, 
We can see that every day in swift-evolution and for that matter 
all other HCSPL (C#, C++, Python, ObjC etc) related forums.

HCSPL are in a sense a traditional compromise to "The Machine” 
and enables us -within the limitations  of our current state of main 
stream technology- to make highly optimised fast running compiled applications. 
That we know is the virtue of hard coded static languages. 
"The Machine" however gets more advanced and faster day by day 
thereby diminishing the need for HCSPL in its course. 

However, (as far as I know) , due to the nature of HCSPL, like Swift, 
there is no (direct and supported and convenient) way supporting 
meta-programming facilities, e.g. to generate define objects (classes), 
and its instances on the fly, that is, at run time. 

In most cases, one can live with this HCSPL "compromise", especially with 
Swift, 
which is very flexible and offers many convenient ways to solve a wide spectrum 
of programming challenges. However, one could think of many applications like
 in AI where applications can improve and extend themselves, learning to adjust 
and adapt to their environment, thereby altering and tuning its performance, 
like our brains do...naturally. 
In contrast, a HCSPL forces one to match one's problem solving to the language 
elements that are available in the HCSPL. In a sense it's like having a big box 
with Lego bricks, that is predefined discrete elements, which allow one to 
build things 
with it, however it still remains limited as Lego. 
This is not the case with a dynamic language like Smalltalk.

Since ca 1980 I have a high interest in Smalltalk (and other OOP dynamic
programming languages too). Some would argue that Smalltalk is a 
programming language, but take a closer look, (e.g. with Pharo).
It is just a relatively small set of mainly syntactic rules defining the 
environment wherein the Smalltalk system lives (almost literally) as a 
dynamic object hierarchy, were everything is an object, which as we know 
is a completely different approach compared to HCSPLs.

Before Swift had arrived, my hope was that the successor of Objective C 
would be Smalltalk, or at least Smalltalk  as a breeding environment for 
developing macOS, iOS, tvOS and watchOS applications. In this role it would then
be desirable that the apps thus produced are "closed apps" so to speak, that is 
that 
the development environment  is not available to the end-user. 
The thought of a e.g. "new Xcode/Smalltalk" being the next Apple development 
environment seemed reasonable, also because ObjectiveC had features 
inspired by Smalltalk. (as all OOP languages have) 
Alas, it didn't happen..but I keep dreaming... 

Perhaps out of context, one then might ask how to interface that 
Xcode/Smalltalk to all those existing libraries (Cocoa UIKit etc.) 
This can be done by letting Smalltalk crawl through all API definitions,
generating its own interface classes dynamically. This sounds ambitious 
but it can be done. Something  a HCSPL like Swift could never do as it is. 

And now we don't have Smalltalk but instead Swift, not bad at all, currently 
I find it the most advanced HCSPL now available.  

However, my verbose text here could be food for thoughts: 

Is it possible to have best of (these completely different) both worlds? 
Would it be possible in Swift to have facilities to generate objects 
dynamically at runtime? and, if desirable, how can such be implemented?


Kind Regards
TedvG

> On Sep 30, 2016, at 9:40 AM, Jay Abbott  > wrote:

> 

> Robert,

> 

> What it does is allow developers to extend the language to do things that it 
> doesn't support. Associated Objects is just a flexible way to allow 
> developers to do that, and that's how I used it in Objective-C, so that's 
> what I thought of in Swift when I found that "I want to do  but the 
> language doesn't support it". Maybe there's a completely different way to 
> achieve the same thing - but I just went with what I know.


"I want to do  but the language doesn't support it” is the whole reason for 
this list!  I want to know what “” is in order to wrap my head around your 
proposal better. I’m not here to invalidate your work with a slew of 
criticisms, I’m just trying to understand your proposal by probing you about it.


> So it's difficult to come up with concrete examples of "things a developer 
> might want

Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Brent Royal-Gordon via swift-evolution
> On Sep 29, 2016, at 9:21 PM, Xiaodi Wu  wrote:
> 
> Can you elaborate on your two reasons for the proposed Type?
> 
> In particular, what do you mean by inheritable and non-inheritable members of 
> T? Where do these come into play? How is the current T.Type deficient in this 
> respect?

Consider a snippet of code like this:

class A { init(a: Int) { } }
class B: A { init(b: Int) { super.init(a: b) } }

You can call `A.init(a:)` directly:

A(a: 0)
A.self.init(a: 0)

However, if you try to assign `A`'s type instance to a variable and do it 
through there, you can't:

let aType: A.Type = A.self
aType.init(a: 0)// Error: constructing an object of 
class type 'A' with a metatype value must use a 'required' initializer

This is a reflection of the fact that an `A.Type` could be `A.self` or `B.self` 
(or any other subclass of `A`), and `B.self` may not have an `init(a:)`.

`Type` does not have this problem because it *is* guaranteed to be an `A`. 
It can express initializers and potentially anything else we might add that 
doesn't get inherited.

Of course, that isn't hugely useful right now because `Type` only has one 
instance, and you can just refer to that instance directly. But I don't like 
that this distinction is unutterable; `Type` corrects that.

And I think we may have features in the future where this is useful. For 
instance, if reflection ever gains the ability to access non-stored-property 
members, the distinction between `Subtype` and `Type` may become 
important. And if we ever get the ability to conform metatypes to protocols, I 
think non-inheritable conformances may be a good thing.

> Regarding (2), it is already possible to do precise type matches using `==` 
> instead of `is` (see corelibs-foundation for extensive uses). What does the 
> proposal offer that goes beyond what we currently have?

`as?` compatibility, I suppose? Honestly, that's just something I noticed when 
I was writing it up. It might not be important.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Review] SE-0143: Conditional Conformances

2016-09-30 Thread Douglas Gregor via swift-evolution

> On Sep 30, 2016, at 1:41 PM, Dave Abrahams  wrote:
> 
> 
> on Fri Sep 30 2016, Douglas Gregor  wrote:
> 
>>> On Sep 29, 2016, at 10:16 PM, Dave Abrahams via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> Obviously I'm a huge +1 for this feature, but I have some concerns and
>>> questions about the particulars.
>> 
>>> 
>>> on Wed Sep 28 2016, Joe Groff  wrote:
>>> 
 Conditional conformances also have a run-time aspect, because a
 dynamic check for a protocol conformance might rely on the evaluation
 of the extra requirements needed to successfully use a conditional
 conformance. For example:
 
 ```swift
 protocol P {
 func doSomething()
 }
 
 struct S: P {
 func doSomething() { print("S") }
 }
 
 // Array conforms to P if it's element type conforms to P
 extension Array: P where Element: P {
 func doSomething() {
   for value in self {
 value.doSomething()
   }
 }
 }
 
 // Dynamically query and use conformance to P.
 func doSomethingIfP(_ value: Any) {
 if let p = value as? P {
   p.doSomething()
 } else {
   print("Not a P")
 }
 }
 
 doSomethingIfP([S(), S(), S()]) // prints "S" three times
 doSomethingIfP([1, 2, 3])   // prints "Not a P"
 ```
 
 The `if-let` in `doSomethingIfP(_:)` dynamically queries whether the
 type stored in `value` conforms to the protocol `P`. In the case of an
 `Array`, that conformance is conditional, which requires another
 dynamic lookup to determine whether the element type conforms to `P`:
 in the first call to `doSomethingIfP(_:)`, the lookup finds the
 conformance of `S` to `P`. In the second case, there is no conformance
 of `Int` to `P`, so the conditional conformance cannot be used. The
 desire for this dynamic behavior motivates some of the design
 decisions in this proposal.
>>> 
>>> Whether a dynamic evaluation is required at this point seems to depend
>>> on how you represent conformance.  Saying “Array conforms conditionally”
>>> treats Array as a type, but it might be simpler to treat Array as a
>>> family of concrete types.
>> 
>> This is already the case in the runtime; we specialize the metadata for 
>> generic types.
>> 
>>> I always envisined it this way: at the moment
>>> a module using the concrete type Array comes together with an
>>> extension (either in that module or in another) that makes Array
>>> conform to Equatable depending on properties of T, that extension is
>>> evaluated and Array is marked as conforming or not.
>> 
>> If the protocol, Array, and Foo all come from different modules, this
>> process happens at runtime. Yes, the optimizer could specialize the
>> conformance at compile time in many common cases, but you can’t see
>> every possible specialization without whole-program analysis, so it
>> doesn’t change the model.
>> 
>>> Then asking
>>> about a type's conformance is always a simple thing.  But I suppose
>>> which approach wins is dependent on many factors, and the other way can
>>> be thought of as adding lazy evaluation to the basic model, so if this
>>> adds nothing to your thinking please excuse the static.
>> 
>> Without whole-program information, you need to have the runtime
>> capability (or disallow the use of this feature in runtime
>> queries). Static specialization can be considered an optimization to
>> this model.
> 
> I know it has to happen at runtime in the worst case.  I was suggesting
> it could happen at load time rather than as a complication of the
> dynamic cast machinery.  In principle all the load-time information can
> be usefully cached on-disk.

You can’t compute it at load time, either. There might be sane cases, but 
here’s a fun one involving existential metatypes:

protocol P { 
  static func makeArray() -> [Self] { return [self] }
}

extension Int: P { }

extension Array: P where Element: P { }

func thwartLoadTime(kind: String) {
let meta: P.Type
if kind == “Int” { meta = Int.self }
else { meta = String.self }

let array: [Any] = meta.makeArray() // Sweet, now I have an 
array of … something.
print(array is P) // true or false?
}

>> But, yes, you’re right that (e.g.) overloading across
>> differently-constrained extensions and protocol extensions means
>> dealing with divergent interfaces… and it’s been a problem for type
>> checker and humans both.
> 
> But that's not going away, so what's the point in bringing it up?

I don’t want us to introduce new features that make the problem worse, which 
allowing overlapping conformances would.

>>> 
>>> Doesn't this break, then?
>>> 
>>>  protocol Equatable { ... }
>>>  protocol Comparable : Equatable { ... }
>>>  protocol Hashable : Equatable { ... }
>>> 
>>>  extension Array : Comparable where T : Comparable {}
>>>  extension Arra

Re: [swift-evolution] associated objects

2016-09-30 Thread Michael Gottesman via swift-evolution

> On Sep 28, 2016, at 9:27 AM, Robert Widmann via swift-evolution 
>  wrote:
> 
> Have you got a significant use-case for this that absolutely can't be solved 
> by extensions or subclassing?
> 
> This does have ABI impact but more concerning for me is the performance 
> impact and that the existing API is not type safe.  
> 
> Using associated objects in ObjC gets you read through the slowest possible 
> deallocation paths and means the runtime is effectively tracking an extra 
> table of pointer tables per object-with-associations.  To make this kind of 
> pattern type safe you would, for example, need to keep track metatype 
> pointers too and use the dynamic cast machinery to check the type on 
> retrieval.

Also from an optimization perspective, it prevents any analysis of the 
side-effects of destructors and causes the optimizer to have to treat all 
operations that could trigger a deinit as potentially doing anything.

Given the pervasiveness of release operations, we really do not want such 
conservatism if we can avoid it. So you really need to balance the need for an 
associated object against creating a language default that is not an 
abstraction that one can not avoid in code that is performance sensitive.

Michael

> 
> ~Robert Widmann
> 
> 2016/09/28 11:26、Jay Abbott via swift-evolution  > のメッセージ:
> 
>> I have implemented Associated Objects (and values) in pure swift here:
>> https://github.com/j-h-a/AssociatedObjects 
>> 
>> 
>> The README is very short and straight-forward so I won't re-describe it here.
>> 
>> The implementation isn't great, but it's a small and simple proof of 
>> concept. I have further extended this (not in GH, but very simple and happy 
>> to share if anyone cares) to add dynamic methods using closures onto 
>> individual object instances. Useful for user interactions, or adding 
>> 'actions' to objects.
>> 
>> I'd like to propose that this or something similar be added to the standard 
>> library. It could potentially even be added to AnyObject so that developers 
>> can use it without having to declare an extension for whichever classes they 
>> want to use it on.
>> 
>> As mentioned, this can easily be extended (either in the standard library or 
>> by developers) to add closures dynamically to any object, or to any class, 
>> which could serve as a useful way for those not concerned with type safety 
>> and the like to get some dynamic behaviour in there in the shorter term. 
>> With a little language support it could even be used to implement stored 
>> properties in extensions very easily.
>> 
>> A better implementation would need some language changes - specifically 
>> deinit hooks (has that ever been discussed?) because of the way weak 
>> references are lazily zeroed. Another implementation improvement might 
>> lazily add the dictionary to each object instead of storing it globally - 
>> not sure if this would have ABI implications.
>> 
>> Interested in feedback and thoughts :)
>> ___
>> 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] associated objects

2016-09-30 Thread Chris Lattner via swift-evolution
On Sep 30, 2016, at 2:51 PM, Ted F.A. van Gaalen via swift-evolution 
 wrote:
> Is it possible to have best of (these completely different) both worlds? 

Yes, of course it is.  Your email spends a lot of words trying to form a false 
dichotomy.  Swift can definitely have both awesome dynamic features while still 
having performance, predictability and safety.

> Would it be possible in Swift to have facilities to generate objects 
> dynamically at runtime? and, if desirable, how can such be implemented?

Here’s an extant implementation that you can use today:
https://github.com/Zewo/Reflection

I’m sure it isn’t ideal, but it proves that it can be done.  When we have 
bandwidth to reevaluate this area from first principles, I’m sure we can make 
improvements on it.

I will grant you that Smalltalk is a beautiful language in its simplicity, but 
for that simplicity it makes many tradeoffs that we’re not willing to make.  We 
are willing to make the internal implementation of Swift complex if that means 
that we get a beautiful model for programmers - one that preserves the virtues 
of safety-by-default, predictability, performance, and joy-to-develop-in.

The meme of “Swift can never (or will never) support dynamic features” is 
tired, and also wildly inaccurate.

-Chris

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


Re: [swift-evolution] [Review] SE-0143: Conditional Conformances

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

on Fri Sep 30 2016, Douglas Gregor  wrote:

>> On Sep 30, 2016, at 1:41 PM, Dave Abrahams  wrote:
>> 
>> 
>> on Fri Sep 30 2016, Douglas Gregor  wrote:
>> 
>
 On Sep 29, 2016, at 10:16 PM, Dave Abrahams via swift-evolution 
  wrote:
 
 
 Obviously I'm a huge +1 for this feature, but I have some concerns and
 questions about the particulars.
>>> 
 
 on Wed Sep 28 2016, Joe Groff  wrote:
 
> Conditional conformances also have a run-time aspect, because a
> dynamic check for a protocol conformance might rely on the evaluation
> of the extra requirements needed to successfully use a conditional
> conformance. For example:
> 
> ```swift
> protocol P {
> func doSomething()
> }
> 
> struct S: P {
> func doSomething() { print("S") }
> }
> 
> // Array conforms to P if it's element type conforms to P
> extension Array: P where Element: P {
> func doSomething() {
>   for value in self {
> value.doSomething()
>   }
> }
> }
> 
> // Dynamically query and use conformance to P.
> func doSomethingIfP(_ value: Any) {
> if let p = value as? P {
>   p.doSomething()
> } else {
>   print("Not a P")
> }
> }
> 
> doSomethingIfP([S(), S(), S()]) // prints "S" three times
> doSomethingIfP([1, 2, 3])   // prints "Not a P"
> ```
> 
> The `if-let` in `doSomethingIfP(_:)` dynamically queries whether the
> type stored in `value` conforms to the protocol `P`. In the case of an
> `Array`, that conformance is conditional, which requires another
> dynamic lookup to determine whether the element type conforms to `P`:
> in the first call to `doSomethingIfP(_:)`, the lookup finds the
> conformance of `S` to `P`. In the second case, there is no conformance
> of `Int` to `P`, so the conditional conformance cannot be used. The
> desire for this dynamic behavior motivates some of the design
> decisions in this proposal.
 
 Whether a dynamic evaluation is required at this point seems to depend
 on how you represent conformance.  Saying “Array conforms conditionally”
 treats Array as a type, but it might be simpler to treat Array as a
 family of concrete types.
>>> 
>>> This is already the case in the runtime; we specialize the metadata for 
>>> generic types.
>>> 
 I always envisined it this way: at the moment
 a module using the concrete type Array comes together with an
 extension (either in that module or in another) that makes Array
 conform to Equatable depending on properties of T, that extension is
 evaluated and Array is marked as conforming or not.
>>> 
>>> If the protocol, Array, and Foo all come from different modules, this
>>> process happens at runtime. Yes, the optimizer could specialize the
>>> conformance at compile time in many common cases, but you can’t see
>>> every possible specialization without whole-program analysis, so it
>>> doesn’t change the model.
>>> 
 Then asking
 about a type's conformance is always a simple thing.  But I suppose
 which approach wins is dependent on many factors, and the other way can
 be thought of as adding lazy evaluation to the basic model, so if this
 adds nothing to your thinking please excuse the static.
>>> 
>>> Without whole-program information, you need to have the runtime
>>> capability (or disallow the use of this feature in runtime
>>> queries). Static specialization can be considered an optimization to
>>> this model.
>> 
>> I know it has to happen at runtime in the worst case.  I was suggesting
>> it could happen at load time rather than as a complication of the
>> dynamic cast machinery.  In principle all the load-time information can
>> be usefully cached on-disk.
>
> You can’t compute it at load time, either. There might be sane cases, but 
> here’s a fun one involving existential metatypes:
>
>   protocol P { 
> static func makeArray() -> [Self] { return [self] }
>   }
>
>   extension Int: P { }
>
>   extension Array: P where Element: P { }
>
>   func thwartLoadTime(kind: String) {
>   let meta: P.Type
>   if kind == “Int” { meta = Int.self }
>   else { meta = String.self }
>
>   let array: [Any] = meta.makeArray() // Sweet, now I have an 
> array of … something.
>   print(array is P) // true or false?
>   }

And some people think Swift isn't dynamic enough?! ;-)

>>> But, yes, you’re right that (e.g.) overloading across
>>> differently-constrained extensions and protocol extensions means
>>> dealing with divergent interfaces… and it’s been a problem for type
>>> checker and humans both.
>> 
>> But that's not going away, so what's the point in bringing it up?
>
> I don’t want us to introduce new features that make the problem worse, which 
> allowing overlapping conformances would.
>
 
 Doesn't t

Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Xiaodi Wu via swift-evolution
On Fri, Sep 30, 2016 at 5:56 PM, Brent Royal-Gordon 
wrote:

> > On Sep 29, 2016, at 9:21 PM, Xiaodi Wu  wrote:
> >
> > Can you elaborate on your two reasons for the proposed Type?
> >
> > In particular, what do you mean by inheritable and non-inheritable
> members of T? Where do these come into play? How is the current T.Type
> deficient in this respect?
>
> Consider a snippet of code like this:
>
> class A { init(a: Int) { } }
> class B: A { init(b: Int) { super.init(a: b) } }
>
> You can call `A.init(a:)` directly:
>
> A(a: 0)
> A.self.init(a: 0)
>
> However, if you try to assign `A`'s type instance to a variable and do it
> through there, you can't:
>
> let aType: A.Type = A.self
> aType.init(a: 0)// Error: constructing an object
> of class type 'A' with a metatype value must use a 'required' initializer
>
> This is a reflection of the fact that an `A.Type` could be `A.self` or
> `B.self` (or any other subclass of `A`), and `B.self` may not have an
> `init(a:)`.
>
> `Type` does not have this problem because it *is* guaranteed to be an
> `A`. It can express initializers and potentially anything else we might add
> that doesn't get inherited.
>
> Of course, that isn't hugely useful right now because `Type` only has
> one instance, and you can just refer to that instance directly. But I don't
> like that this distinction is unutterable; `Type` corrects that.
>
> And I think we may have features in the future where this is useful. For
> instance, if reflection ever gains the ability to access
> non-stored-property members, the distinction between `Subtype` and
> `Type` may become important. And if we ever get the ability to conform
> metatypes to protocols, I think non-inheritable conformances may be a good
> thing.
>
> > Regarding (2), it is already possible to do precise type matches using
> `==` instead of `is` (see corelibs-foundation for extensive uses). What
> does the proposal offer that goes beyond what we currently have?
>
> `as?` compatibility, I suppose? Honestly, that's just something I noticed
> when I was writing it up. It might not be important.
>

This is a very clear answer. So for my understanding, what you're saying
is: without other language features not yet proposed, `Type` does not in
itself enable a particularly notable use case that's not currently possible
today. It is being included in this proposal because the original design of
Swift lumped two things together for simplicity, but you disagree with that
design decision and want the distinction to be utterable. Is that more or
less the gist of it?

--
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Conditional conformances

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

on Fri Sep 30 2016, Matthew Johnson  wrote:

>> It’s a valid concern, and I’m sure it does come up in practice. Let’s create 
>> a small, self-contained example:
>> 
>> protocol P {
>>   func f()
>> }
>> 
>> protocol Q: P { }
>> 
>> struct X { let t: T}
>> 
>> extension X: P where T: P {
>>   func f() {
>> /* general but slow */
>>   }
>> }
>> 
>> extension X where T: Q {
>>   func f() {
>> /* fast because it takes advantage of T: Q */
>>   }
>> }
>> 
>> struct IsQ : Q { }
>> 
>> func generic(_ value: u) {
>>   value.f()
>> }
>> 
>> generic(X())
>> 
>> We’d like for the call to “value.f()” to get the fast version of f()
>> from the second extension, but the proposal doesn’t do that: the
>> conformance to P is “locked in” to the first extension.

I suppose that's true even if the second extension introduces X : Q?

>> If we assume that we can see all of the potential implementations of
>> “f” to which we might want to dispatch, we could implement some
>> dynamic scheme that tries to pick the most specialized one. Of
>> course, as with overlapping conformances in general, this selection
>> process could result in ambiguities.
>
> This is what I suspected.  I’ll defer to Dave A on how big a concern
> this is, but it seems to me like a bit of a slippery slope towards
> sub-optimal performance.

Well, it's unfortunate.  We have a similar problem today due to the lack
of conditional conformance, and we deal with it by injecting an
underscored requirement where it doesn't belong, then dispatch through
that.  I wonder if the workaround for this limitation is like that, or
something completely different.

Does this work?  If not, why not?  If so, what makes it fundamentally
different, since it is trying to express the same thing through
different means?

-

public protocol P {
  func f()
}

public protocol Q: P { }

public struct X { let t: T}

internal protocol XFImpl {
  associatedtype TT: P
  static func f(X)
}

extension XFImpl {
 static func f(X) { /* general but slow */ }
}

extension XFImpl where TT: Q {
  static func f(X) { /* fast because it takes advantage of T: Q */ }
}

extension X: P where T: P {
  struct FImpl : XFImpl {
typealias TT = T
  }

  func f() {
FImpl.f(self)
  }
}

struct IsQ : Q { }

func generic(_ value: u) {
  value.f()
}

generic(X())

-- 
-Dave

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


Re: [swift-evolution] [Proposal draft] Introducing `indexed()` collections

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

on Wed Sep 28 2016, Erica Sadun  wrote:

> Indices have a specific, fixed meaning in Swift, which are used to create 
> valid collection
> subscripts. This proposal introduces indexed() to produce a more semantically 
> relevant sequence by
> pairing a collection's indices with its members. While it is trivial to 
> create a solution in Swift,
> the most common developer approach shown here calculates indexes twice:
>
> extension Collection {
> /// Returns a sequence of pairs (*idx*, *x*), where *idx* represents a
> /// consecutive collection index, and *x* represents an element of
> /// the sequence.
> func indexed() -> Zip2Sequence {
> return zip(indices, self)
> }
> }

How does this calculate indices twice?

> Incrementing an index in some collections can be unnecessarily
> costly. 

Seems like it's only *unnecessarily* costly in badly implemented
collections?

> In a lazy filtered collection, an index increment is potentially
> O(N). We feel this is better addressed introducing a new function into
> the Standard Library to provide a more efficient design that avoids
> the attractive nuisance of the "obvious" solution.

I am generally opposed to adding this.  The usual solution developers
will reach for here is:

for i in x.indices {
somethingWith(x[i])
}

zip(indices, self) is only suboptimal for lazy filtered sequences, which
should be used with care anyhow (see the note here:
http://swiftdoc.org/v3.0/type/LazyFilterCollection/).

If you really need a lazy sequence of pairs that's optimal with lazy
filtered sequences, 

x.indices.lazy.map { ($0, x[$0]) }

is a good solution and pretty easy to write.

-- 
-Dave

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


Re: [swift-evolution] [Proposal draft] Introducing `indexed()` collections

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

on Wed Sep 28 2016, Robert Widmann  wrote:

> +1.  One of those things where you wonder why this wasn't the default 
> behavior.

FWIW, it's because what Nevin did below is easy to write, but getting
integer offsets isn't easy, at least not without introducing your own
counter state.

> ~Robert Widmann
>
> 2016/09/28 14:23、Nevin Brackett-Rozinsky via swift-evolution
>  のメッセージ:
>
>> +1, I have been mildly surprised that this was not already present.
>> 
>> My workaround heretofore has been:
>> 
>> for idx in abc.indices {
>>   let val = abc[i]
>>   // do something with idx and val
>> }
>> 
>> Nevin
>> 
>> 
>>> On Wed, Sep 28, 2016 at 1:55 PM, Erica Sadun via swift-evolution 
>>>  wrote:
>>> Gist here: https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2
>>> 
>>> Introducing indexed() collections
>>> Proposal: TBD
>>> Author: Erica Sadun, Nate Cook, Jacob Bandes-Storch, Kevin Ballard
>>> Status: TBD
>>> Review manager: TBD
>>> Introduction
>>> 
>>> This proposal introduces indexed() to the standard library, a method on 
>>> collections that returns an (index, element) tuple sequence.
>>> 
>>> Swift-evolution thread: TBD
>>> 
>>> Motivation
>>> 
>>> The standard library's enumerated() method returns a sequence of pairs 
>>> enumerating a sequence. The pair's first member is a monotonically 
>>> incrementing integer starting at zero, and the second member is the 
>>> corresponding element of the sequence. When working with arrays, the 
>>> integer is coincidentally the same type and value as an Array index but the 
>>> enumerated value is not generated with index-specific semantics. This may 
>>> lead to confusion when developers attempt to subscript a non-array 
>>> collection with enumerated integers. It can introduce serious bugs when 
>>> developers use enumerated()-based integer subscripting with non-zero-based 
>>> array slices.
>>> 
>>> Indices have a specific, fixed meaning in Swift, which are used to create 
>>> valid collection subscripts. This proposal introduces indexed() to produce 
>>> a more semantically relevant sequence by pairing a collection's indices 
>>> with its members. While it is trivial to create a solution in Swift, the 
>>> most common developer approach shown here calculates indexes twice: 
>>> 
>>> extension Collection {
>>> /// Returns a sequence of pairs (*idx*, *x*), where *idx* represents a
>>> /// consecutive collection index, and *x* represents an element of
>>> /// the sequence.
>>> func indexed() -> Zip2Sequence {
>>> return zip(indices, self)
>>> }
>>> }
>>> Incrementing an index in some collections can be unnecessarily costly. In a 
>>> lazy filtered collection, an index increment is potentially O(N). We feel 
>>> this is better addressed introducing a new function into the Standard 
>>> Library to provide a more efficient design that avoids the attractive 
>>> nuisance of the "obvious" solution.
>>> 
>>> Detailed Design
>>> 
>>> Our vision of indexed() bypasses duplicated index generation with their 
>>> potentially high computation costs. We'd create an iterator that calculates 
>>> each index once and then applies that index to subscript the collection. 
>>> Implementation would take place through IndexedSequence, similar to 
>>> EnumeratedSequence.
>>> 
>>> Impact on Existing Code
>>> 
>>> This proposal is purely additive and has no impact on existing code.
>>> 
>>> Alternatives Considered
>>> 
>>> Not yet
>>> 
>>> ___
>>> 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
>

-- 
-Dave

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


Re: [swift-evolution] [Pitch] Refactor Metatypes

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

> On Sep 29, 2016, at 7:29 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Sep 29, 2016, at 3:24 PM, Russ Bishop via swift-evolution 
>>  wrote:
>> 
>> Why would we not have type(of:) and subtype(of:)? Why would I want the 
>> Subtype instead of the specific Type?
> 
> Let's turn this around. Suppose you write:
> 
>   let obj: NSObject = …
>   let ty = type(of: obj)
> 
> What is `ty`? Well, it's a `Type`, and there's only one of those: 
> `NSObject.self`. So there's only one possible instance that could be assigned 
> to that variable.
> 
> This is true in general: If `type(of:)` returns `Type`, then it can only 
> have one possible return value. In other words, the return value of 
> `type(of:)` would always be the *static* type of the variable, not its 
> dynamic type. There may be some narrow cases where that'd be useful, but 99% 
> of the time, you want `subtype(of:)` because you're trying to discover which 
> of many dynamic subtypes of the static type you're actually dealing with. So 
> most uses of `type(of:)` would probably be mistaken attempts to perform 
> `subtype(of:)` instead.
> 
>> What is the rationale for losing the meta type relationships by having 
>> Type not be a subtype of Type?
> 
> The relationships aren't lost; they're just expressed through `Subtype`, not 
> `Type`.
> 
> Again, turn this around. `Subtype` is the normal thing that you'll want to 
> use most of the time. `Type` is the weird thing whose existence is hard to 
> explain. (One version of this proposal used `Type` for `Subtype` and 
> `ExactType` for `Type` in order to imply that subtype is usually what you 
> want, but some of the contributors weren't happy with that.)
> 
> So, `Type` is the weird thing. Why does it exist? Two reasons:
> 
> 1. `Subtype` only includes *inheritable* type members of `T`. `Type` 
> also includes *non-inheritable* members, particularly non-required 
> initializers.
> 
> 2. It allows precise type matches: `subty is Subtype` would match 
> for any subtype of `NSObject`, whereas `subty is Type` would only 
> match for `NSObject` itself.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

I understand what you’re getting at. 

This topic is confusing enough that I think it warrants being extremely clear 
about the naming. Type and Subtype feel like a class hierarchy and that’s not 
exactly what we are doing here. If Type represents the static type of T then 
let’s just call it StaticType. If the thing most people want to work with is 
the dynamic type Subtype then let’s just call it that: DynamicType.

Now this becomes really clear:

class A { }
class B: A { }

//clearly only ever represents A as a type
let metatype_1 = statictype(of: A())

//clearly might dynamically be A, B, or any subclass
let metatype_2 = dynamictype(of: A())


It also becomes trivially easy to explain because the name follows the 
explanation. Why can I only use required initializers on DynamicType? 
Because we don’t know if the initializer is available; the dynamic type may 
differ at runtime. StaticType knows exactly what is available on A because 
it is statically known at compile time.


Russ

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


Re: [swift-evolution] [Review] SE-0143: Conditional Conformances

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

> On Sep 28, 2016, at 3:15 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of “Conditional Conformances” begins now and runs through October 
> 7. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0143-conditional-conformances.md
>  
> 
> What is your evaluation of the proposal?
+1. 

I still think there is some possibility of relaxing the overlapping constraint 
problem but I’d rather have this feature in Swift 4 since it’s such a big win. 
The rules can always be relaxed later if we come up with a workable model.

> Is the problem being addressed significant enough to warrant a change to 
> Swift?
Definitely

> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
I’ve been thinking about it for some time and regularly run into the problem it 
solves. Participated in the draft proposal thread as well.


Russ

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


Re: [swift-evolution] [Pitch] Making some RawRepresentable things bridge to ObjC as their raw value

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

> On Sep 29, 2016, at 11:45 AM, Douglas Gregor via swift-evolution 
>  wrote:
>> 
> 
> 
> Personally, I consider the first one to be a fairly-low-risk extension to 
> SE-0139 that’s borderline bug-fix. We already know that those types have weak 
> numeric representations in Objective-C because they come from Objective-C, so 
> losing some of the type info by bridging to Objective-C is (IMO) falls out of 
> having strong types in Swift for weaker types in Objective-C.
> 
> The second one makes me a little nervous, I think because it weakens typing 
> for types defined in Swift. These types don’t naturally have Objective-C 
> counterparts, so if we’re going to weaken the types, it feels like we should 
> only do so via some explicit conformance (e.g., to a publicly-available form 
> of _ObjectiveCBridgeable).
> 
>   - Doug
> 

I’m up for reviving the ObjectiveCBridgeable proposal :)


Russ

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