Re: [swift-evolution] [Review] SE-0091: Improving operator requirements in protocols

2016-05-25 Thread plx via swift-evolution

> On May 24, 2016, at 11:13 AM, Tony Allevato via swift-evolution 
>  wrote:
> 
> On Mon, May 23, 2016 at 9:20 PM David Sweeris via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> > On May 18, 2016, at 18:07, plx via swift-evolution 
> > mailto:swift-evolution@swift.org>> wrote:
> >
> > How hard would it be to e.g. simply allow something like this:
> >
> >  func ==(lhs: T, rhs: T) -> Bool {
> >return lhs T.== rhs
> >  }
> >
> > …instead of the `T.==(lhs,rhs)` syntax?
> 
> Yeah, I've been meaning to suggest that. And 'T.++(x)' and '(x)T.++' for 
> prefix and postfix, respectfully.
> 
> The "fully-qualified operator" syntax was one that was discussed in some of 
> the original e-mail threads. It was part an earlier draft of the proposal, 
> but I changed it to the function call syntax because
> 
> - visually, it's a bit tricky to parse with the eyes

I agree, but IMHO I would anticipate that each time I needed to use a 
pre/post-fix method, I’d have to go to the reference and double-check whether:

  T.++(prefix: foo) 

…means  “`foo` is prefixed-to `++`” or “the prefix `++` is prefixed-before 
`foo`”, and vice-versa for `postfix`; the point of confusion is that *usually* 
the argument label describe the argument, not the “function position” as it 
were. 

Not likely to be a huge problem but likely to be confusing on the rare 
occasions it’s actually necessary to pick the right one.

Something like `prefixedTo:` and `postfixedTo:` would be more self-explanatory 
but seem clunky; perhaps a better formulation is possible here?

> - I wasn't sure whether it would pose similar problems for the compiler to 
> parse
> - It doesn't solve the (admittedly edge case) issue of not being able to 
> refer distinctly to prefix/postfix operators that have the same name as a 
> first-class function without wrapping the invocation in a closure

It’s definitely an edge case but in some ways it just illustrates the tradeoff 
being made under this proposal. For this *specific* use case the following are 
IMHO increasingly self-explanatory:

- `foo.map(T.++)`
- `foo.map(T.++(prefix:))`
- `foo.map(T.incrementThenReturn(_:))`

…with the last approach being clearer in this one scenario, but still having 
all the other drawbacks that motivated to this proposal. 

I can’t think of a natural scenario where this might come up; maybe something 
with `!` but even there I can’t think of one.

> - Chris Lattner recommended changing it to the function call syntax after a 
> core team discussion before the proposal PR was accepted, so it's possible 
> they have more insight into the parsing/implementation issues?

That seems likely and reasonable.

After reflecting on it the main gripe I’d have is I don’t think the 
`prefix:/postfix:` labels do an ideal job of their roles in this proposal, but 
there’s probably a better approach to be found within the confines of “normal 
function” syntax.

> 
>  
> 
> - Dave Sweeris
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-26 Thread plx via swift-evolution
I really want synthesized equality (etc.), but having seen the previous 
discussions on this and related topics I am not sure that directly-deriving the 
`==` function is the right approach. 

The main reason I say this is that although this works great for the easy case 
— all fields equatable, do the obvious thing! — sooner or later people will 
want to customize it, which would ideally allow someone to say “do the obvious 
thing for a,b,c but let me handle d and e”, e.g. still get synthesis for the 
easy parts…but an approach that directly-synthesizes `==` for a type seems like 
it’ll be difficult to expand to support such customization.

Suppose instead that we had a “magic function” `T#memberwiseEqual(_:_:)` we 
could invoke like so:
 
  // the details are *very* bikesheddable here:
  func ==(lhs: Foo, rhs: Foo) -> Bool {
return Foo#memberwiseEqual(lhs,rhs) // `#` b/c of "compiler magic”
// ^ compiler error iff any of `Foo`’s members aren’t Equatable
  }

…which’d expand to the expected “lhs.a == rhs.a && lhs.b == rhs.b && …”. 

For trivial equatable synthesis this isn’t as nice as a full automatic 
derivation, but it seems like an *approach* that’d be much-better positioned 
for future expansion and enhancement, e.g.:

  extension Foo: Equatable {

   // mock syntax; probably too ambiguous for actual use but i think the idea 
is clear:
   private static func boringComponentsEqual(lhs: Foo, _ rhs: Foo) -> Bool {
  return Foo(boring,boring2,boringIII)#memberwiseEqual(lhs,rhs)
   }

  }

  func ==(lhs: Foo, rhs: Foo) -> Bool {
return Foo.boringComponentsEqual(lhs,rhs) && // non-trivial equality logic 
here
  }

…as opposed to trying to retrofit various “customizations" onto a system that 
directly synthesizes `==` (without exposing any “internals", so to speak).

You can easily imagine a similar `#casewiseEqual` for enums (it seems likely to 
be trickier, but not impossible), and again a #memberwiseHash for hashing, and 
so on.

I think you can summarize the above as “all-in-one derivation is appealing, but 
I think pragmatically and looking-ahead it’s a better move to expose the 
'synthesis mechanism’ itself (leaving it the user to do the 'final assembly’)”.

> On May 25, 2016, at 1:28 PM, Tony Allevato via swift-evolution 
>  wrote:
> 
> I was inspired to put together a draft proposal based on an older discussion 
> in the Universal Equality, Hashability, and Comparability thread 
>  > that 
> recently got necromanced (thanks Mark Sands!).
> 
> I'm guessing that this would be a significant enough change that it's not 
> possible for the Swift 3 timeline, but it's something that would benefit 
> enough people that I want to make sure the discussion stays alive. If there 
> are enough good feelings about it, I'll move it from my gist into an actual 
> proposal PR.

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


Re: [swift-evolution] [Pre-proposal] Replace [Foo] With CollectionType

2016-05-27 Thread plx via swift-evolution
Late response!

As-specified, although I understand the *motivation* for this suggestion, I 
can’t support the specific proposal whatsoever.

That said, I do think there’d be a lot of value in a way to add “convenience 
type predicates” (terrible name, please improve!) to declarations, so that e.g.:

  protocol Sequence {

// one possibility for a declaration:
typealias of == S: Self where S.Iterator.Element == E

  }

…would allow you to write your examples like this:

  // sequence-accepting variant
  func doSomething>(values: S) { … }

  // hopefully, this would work also:
  func doSomething>

…either as an extension of the existing generic-typealias syntax or as a 
separate-but-similar feature.

For the Sequence/Collection it’s a lot of work for IMHO a rather minor 
convenience, but for more-complex type associated-type relationships it could 
start to pay its own way.

> On May 24, 2016, at 12:57 PM, Haravikk via swift-evolution 
>  wrote:
> 
> One thing that I see a lot in code, and sometimes have to stop myself from 
> doing, is using shorthand array types, such as [Foo], in function 
> declarations where CollectionType could just as easily be used. For example, 
> the following two declarations can take collections of values, but the first 
> will only take them in the form of an Array:
> 
>   func doSomething(values:[Foo]) { … }
>   func doSomething C.Generator.Element:Foo>(values:C) { … }
> 
> The latter form is something that new users of Swift tend not to know they 
> can do, and which even experienced Swift developers may not use for the sake 
> of brevity, but it can come up quite a lot. What I’d like to propose is that 
> [Foo], when used in a function, should produce the latter form behind the 
> scenes, requiring the developer to specify Array if they actually need 
> it to be an Array for some reason. Though this would become inconsistent with 
> variables/properties which would still have to be Array since a type is 
> required.
> 
> 
> An alternative would be if we could specify protocol generics in a more 
> succinct form, for example:
> 
>   func doSomething(values:Collection) { … }
>   func doSomething(values:Sequence) { … } // Many array functions 
> are linear anyway so could just as easily take sequences
> 
> Note: This would not be the same as type-erased wrappers such as 
> AnySequence, but rather a shorthand for "Sequence where 
> Generator.Element:Foo"
> 
> 
> 
> In essence I’m hoping to discuss whether we should try to remove the 
> temptation to limit functions to arrays only or not, or if there are other 
> ways to encourage more use of sequence and collection for flexibility; I try 
> wherever possible to have my methods take sequences if they can, and only 
> take collections if they need to (and never arrays only), but I can 
> understand why not everyone does this, as it’s not the friendliest thing to 
> add and declaring [Foo] looks so much neater.
> ___
> 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] Property reflection

2016-05-27 Thread plx via swift-evolution
I think this proposal should “simmer" until we know what property behaviors 
will look like (or find out they are never happening, etc.). 

The interaction with “property behaviors” seems likely to be quite subtle, even 
for something simple like `lazy`.

For sake of argument, let’s say that a `lazy` declaration like so:

  class SomeClass { 
lazy var foo: Foo = Foo(bar: self.prepareBar())
  }

…gets implicitly-expanded into e.g. something like the below:

  class SomeClass {
 
var foo: Foo {
  guard let foo = _foo else {
_foo = Foo(bar: self.prepareBar())
return _foo
  }
  return foo
}

private var _foo: Foo? = nil

  }

…which immediately exposes a few lazy-specific questions:

- should `foo` be exposed via reflection? (IMHO: yes)
- should `_foo` be exposed via reflection? (IMHO: probably not, but not certain)
- should `foo`’s lazy-ness be exposable? (IMHO: yes, but how exactly?)

…as well as a few more-general questions:

- should computed properties, in general, be exposed to reflection? (IMHO: 
probably not, but there are some exceptions…)
- if user-specified property behaviors get special exposure, how should that 
work?
- how should reflection work for enums/enums-with-payloads? 

Finally, I worry a lot less about the details of getter/setter pairs than I 
worry about being able to use reflection for construction/initialization.

I don’t have any actual proposal on that front, but it seems like it should be 
factored into any reflection design.

> On May 26, 2016, at 8:25 PM, Austin Zheng via swift-evolution 
>  wrote:
> 
> Hi swift-evolution,
> 
> For those who are interested I'd like to present a pre-pre-proposal for 
> reflection upon a type's properties and solicit feedback. 
> 
> First of all, some caveats: this is only a very small piece of what 
> reflection in Swift might look like one day, and it's certainly not the only 
> possible design for such a feature. Reflection comes in many different forms, 
> and "no reflection" is also an option. Deciding what sort of reflection 
> capabilities Swift should support is a prerequisite to stabilizing the 
> runtime API, which I imagine has resilience consequences. I'm not really 
> interested in defending this specific proposal per se, as I am looking for a 
> jumping-off point to explore designs in this space.
> 
> Anyways, here is a gist outlining the public API to the feature: 
> 
> https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a 
> 
> 
> A couple of notes regarding the proposal:
> 
> The API names need improvement. Suggestions welcome.
> 
> It's opt-in: types have to conform to a special protocol for the compiler to 
> generate whatever hooks, metadata, and support code is necessary. Once a type 
> conforms, the interface to the reflection features naturally present 
> themselves as protocol methods. It would be great to allow an extension to 
> retroactively enable reflection on a type vended by another module, although 
> I have no idea how feasible that is.
> 
> It uses "views": there are four types of views, two of each in the following 
> categories: typed vs untyped, get-only versus get-set. A view is a struct 
> representing a property on an instance of a type (or maybe a metatype, for 
> type properties). It allows you to get information about that property (like 
> its name) and try getting and setting its values.
> 
> (You can get a get-only view to a property, and then try and upgrade it later 
> to a get-set view, if the underlying property is get-set. If you don't care 
> about setting, though, you can just work exclusively with get-only views.)
> 
> It supports both typed and untyped access. You can ask for a property view 
> specifically for (e.g.) a `String` property, and if you get one you can be 
> assured that your getting and setting operations will be type safe. You can 
> also ask for an "untyped" property view that exposes the value as an Any, and 
> allows you to try (and possibly fail, with a thrown error) to set the value.
> 
> The requirements part of it is composable. For example, you can imagine a 
> future "FullyReflectable" protocol that simply inherits from 
> "PropertyReflectable", "MethodReflectable", and other reflectable protocols. 
> Or maybe a library requires reflection access to types that it needs to work 
> with, and it can create its own protocols that inherit from 
> "PropertyReflectable" and naturally enforce reflection support on the 
> necessary types.
> 
> It looks a bit cumbersome, but there's room for refinement. Users won't 
> necessarily see all the types, though, and the interface is pretty 
> straightforward:
> 
> ```
> myPerson.typedReadWriteProperty("age")?.set(30)
> 
> try myPerson.allNamedProperties["age"]?.set(30)
> ```
> 
> I'm not yet sure how it should interact with access control (my inclination 
> is that it would only expose the properties you'd be

Re: [swift-evolution] [Returned for revision] SE-0089: Renaming String.init(_: T)

2016-05-27 Thread plx via swift-evolution
I like the design strategy, but I’m having a hard time seeing the value of 
`ValuePreservingStringConvertible`; it’d be easier to evaluate the need for it 
with some concrete examples of types with `description` implementations that:

- aren’t value-preserving
- would cause problems if mistakenly-classified as value-preserving

Relatedly, here are some concrete `description`/`debugDescription` pairs; would 
these `description`s be value-preserving or not?

- a `Wavelength` type
 - description: “650.0 nm”
 - debugDescription: “Wavelength(nanometers: 650.0)”

- an `Angle` type:
  - description: “90.0°”
  - debugDescription: “Angle(πUnits: 0.5)”

…(note that neither type has a corresponding `init?(_ string: String)` 
implementation, and I don’t plan to add one either).

I’m just having trouble coming up with realistic non-value-preserving 
descriptions that’d be *problematic* (as opposed to just, say, unhelpful).

> On May 26, 2016, at 12:08 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Proposal Link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0089-rename-string-reflection-init.md
> 
> The review of "SE-0089: Renaming String.init(_: T)" ran from May 17…23, 
> 2016. The proposal has been *returned for revision* and another round of 
> discussion - the core team would love to see the revised proposal make it 
> into Swift 3.
> 
> The community and core team both want to remove this “footgun” from the 
> standard library, where someone could write "String(x)” with the intention of 
> getting a value-preserving conversion to String, but may instead get a 
> potentially lossy and potentially expensive reflection-based conversion to a 
> String.  After extensive discussion, the core team recommends that the 
> community consider a somewhat more elaborate design:
> 
> - Rename the existing reflection-based "String.init(_: T)” initializer to 
> "String.init(describing: T)” as recommend by the community.  This 
> initializer would rarely be invoked in user code directly.
> 
> - Introduce a new protocol (for sake of discussion, call it 
> “ValuePreservingStringConvertible") that refines CustomStringConvertible but 
> that adds no new requirements.  Conformance to this protocol indicates that 
> the “description” requirement produces a value-preserving representation in 
> String form.
> 
> - Introduce a new unlabeled initializer on String: "init ValuePreservingStringConvertible>(_ v: T) { return v.description }".  This 
> permits the “String(x)” syntax to be used on all values of types that can be 
> converted to string in a value-preserving way.
> 
> - Audit important standard library types (e.g. the integer and floating point 
> types), and make them explicitly conform to ValuePreservingStringConvertible 
> with an explicitly implemented “description” property.
> 
> - As a performance optimization, change the implementation of the string 
> literal interpolation syntax to prefer the unlabeled initializer when 
> interpolating a type that is ValuePreservingStringConvertible or that has 
> otherwise has an unlabeled String initializer, but use the 
> "String.init(describing: T)” initializer if not.
> 
> 
> The expected advantages of this design are:
> 
> - Swift encourages the T(x) syntax for value preserving conversions, and this 
> design ensures that String(x) continues to work for the value preserving 
> cases.
> 
> - This ensures that the String(x) syntax does not accidentally fall off a 
> performance cliff by using the extremely-dynamic reflection mechanism 
> unintentionally.
> 
> - The preferred “I don’t care how you do it, just convert this value to a 
> string somehow” syntax remains string interpolation syntax.  This syntax is 
> efficient in the cases where the String(x) syntax is allowed, but fully 
> general to the other cases where custom convert-to-string code has not been 
> provided.
> 
> 
> Some remaining open questions:
> 
> - Exactly what types should conform to ValuePreservingStringConvertible.  It 
> seems clear that integer, floating point types, and Character can and should 
> conform.  What other types should?
> 
> - Do we need the ValuePreservingStringConvertible at all, or is the existing 
> CustomStringConvertible enough?  We already have a few protocols for handling 
> string convertibility, it would be great to avoid adding another one.
> 
> Thank you to Austin Zheng for driving this proposal forward!
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-27 Thread plx via swift-evolution

> On May 26, 2016, at 1:00 PM, T.J. Usiyan via swift-evolution 
>  wrote:
> 
> A `deriving` keyword, at the very least, is pretty explicitly *not* an 
> all-or-nothing situation. If you want to define equality/hashability for your 
> type manually, don't use `deriving`. This should leave the simplest cases to 
> auto generation and anything more complex should be handled by the developer.

It’s all-or-nothing in the sense you can’t use a naive `deriving` 
implementation to assist in any case where what you need is *almost* the 
trivial implementation, but not quite.

Consider a case like this:

  class QuxEvaluator  {
  
let foo: Foo // Equatable
let bar: Bar // Equatable
let baz: Baz // Equatable

private var quxCache: [QuxIdentifier:Qux] // [Equatable:Equatable] = [:]

// pure function of `foo`, `bar`, `baz`, and `identifier`
// expensive, and uses `quxCache` for memoization 
func qux(for identifier: QuxIdentifier) -> Qux

  }

…if it weren’t for `quxCache` we could easily synthesize `==` for 
`QuxEvaluator`, but the trivial synthesis will yield invalid results due to 
`[QuxIdentifier:Qux]` also being `Equatable` (really: it *will* also be 
equatable once conditional conformances are in place).

So we’re back to e.g. writing this: 

  extension QuxEvaluator : Equatable {

  }

  func ==(lhs: QuxEvaluator, rhs: QuxEvaluator) -> Bool {
return (lhs === rhs) || (lhs.foo == rhs.foo && lhs.bar == rhs.bar && 
lhs.baz == rhs.baz)
  }

…just to omit a single field from the `==` consideration; this is another sense 
in which you can say deriving is an all-or-none; there’s just no way to invoke 
the synthesis mechanism other than for "all fields”.

On the one hand, it’s possible to imagine a finer-grained form of this 
synthesis that’d allow you to e.g. indicate a certain field should be omitted 
(and also perhaps specialize how fields are compared, customize the synthesized 
comparison ordering to put cheaper comparisons earlier, and an endless list of 
other possible requests…).

On the other hand, the memberwise-init proposal had a very similar situation: 
the naive approach was arguably too narrow, but it proved very difficult to 
find a workable balance between customization and implementation complexity 
(leaving it postponed for the foreseeable future); it’d be a pity if synthesis 
like this fell into the same trap.

But, on the gripping hand, I highly suspect that a naive `deriving`/synthesis 
will wind up being too narrowly-useful to really justify; that’s just my 
opinion, of course.

> 
> On Thu, May 26, 2016 at 11:20 AM, L. Mihalkovic  > wrote:
> what i care about is to have a choice about what DEFINES the identity of my 
> values, not just an all-or-nothing situation.
> 
> On May 26, 2016, at 5:18 PM, T.J. Usiyan via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> +1 to a `deriving` keyword
>> 
>> On Thu, May 26, 2016 at 3:58 AM, Michael Peternell via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> Can we just copy&paste the solution from Haskell instead of creating our 
>> own? It's just better in every aspect. Deriving `Equatable` and `Hashable` 
>> would become
>> 
>> struct Polygon deriving Equatable, Hashable {
>> ...
>> }
>> 
>> This has several advantages:
>> - you don't have to guess wether `Equatable` or `Hashable` should be 
>> automatically derived or not.
>> - Deriving becomes an explicit choice.
>> - If you need a custom `Equatable` implementation (for whatever reason), you 
>> can still do it.
>> - It doesn't break any code that is unaware of the change
>> - It can be extended in future versions of Swift, without introducing any 
>> new incompatibilities. For example, `CustomStringConvertible` could be 
>> derived just as easily.
>> - It is compatible with generics. E.g. `struct Shape deriving Equatable` 
>> will make every `Shape` equatable if `X` is equatable. But if `X` is not 
>> equatable, `Shape` can be used as well. (Unless `X` is not used, in which 
>> case every `Shape` would be equatable. Unless something in the definition 
>> of `Shape` makes deriving `Equatable` impossible => this produces an error.)
>> - It is proven to work in production.
>> 
>> -Michael
>> 
>> > Am 26.05.2016 um 03:48 schrieb Mark Sands via swift-evolution 
>> > mailto:swift-evolution@swift.org>>:
>> >
>> > Thanks so much for putting this together, Tony! Glad I was able to be some 
>> > inspiration. :^)
>> >
>> >
>> > On Wed, May 25, 2016 at 1:28 PM, Tony Allevato via swift-evolution 
>> > mailto:swift-evolution@swift.org>> wrote:
>> > I was inspired to put together a draft proposal based on an older 
>> > discussion in the Universal Equality, Hashability, and Comparability 
>> > thread > > > that 
>> > recently got necromanced (thanks Mark Sands!).
>> >
>> > I'm guessing t

Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-27 Thread plx via swift-evolution

> On May 27, 2016, at 10:48 AM, Matthew Johnson  wrote:
> 
>> 
>> On May 27, 2016, at 10:37 AM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On May 26, 2016, at 1:00 PM, T.J. Usiyan via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> A `deriving` keyword, at the very least, is pretty explicitly *not* an 
>>> all-or-nothing situation. If you want to define equality/hashability for 
>>> your type manually, don't use `deriving`. This should leave the simplest 
>>> cases to auto generation and anything more complex should be handled by the 
>>> developer.
>> 
>> It’s all-or-nothing in the sense you can’t use a naive `deriving` 
>> implementation to assist in any case where what you need is *almost* the 
>> trivial implementation, but not quite.
>> 
>> Consider a case like this:
>> 
>>   class QuxEvaluator  {
>>   
>> let foo: Foo // Equatable
>> let bar: Bar // Equatable
>> let baz: Baz // Equatable
>> 
>> private var quxCache: [QuxIdentifier:Qux] // [Equatable:Equatable] = [:]
>> 
>> // pure function of `foo`, `bar`, `baz`, and `identifier`
>> // expensive, and uses `quxCache` for memoization 
>> func qux(for identifier: QuxIdentifier) -> Qux
>> 
>>   }
>> 
>> …if it weren’t for `quxCache` we could easily synthesize `==` for 
>> `QuxEvaluator`, but the trivial synthesis will yield invalid results due to 
>> `[QuxIdentifier:Qux]` also being `Equatable` (really: it *will* also be 
>> equatable once conditional conformances are in place).
>> 
>> So we’re back to e.g. writing this: 
>> 
>>   extension QuxEvaluator : Equatable {
>> 
>>   }
>> 
>>   func ==(lhs: QuxEvaluator, rhs: QuxEvaluator) -> Bool {
>> return (lhs === rhs) || (lhs.foo == rhs.foo && lhs.bar == rhs.bar && 
>> lhs.baz == rhs.baz)
>>   }
>> 
>> …just to omit a single field from the `==` consideration; this is another 
>> sense in which you can say deriving is an all-or-none; there’s just no way 
>> to invoke the synthesis mechanism other than for "all fields”.
> 
> I don’t see why this must necessarily be the case.  Annotations such as you 
> describe below could be taken into account by `deriving`.  `deriving` is just 
> a way to invoke the synthesis mechanism.

Different people are using it differently I think; I agree with you if it’s 
just the name of the invocation, but I think at least some people are using it 
as a shorthand for the “naive” implementation (all fields equatable => 
equatable).

That is, I meant "naive deriving” to refer to something like this (quoting 
Patrick):

> It would fail if not all members were Equatable or Hashable. If it was 
> automatic, you wouldn’t get any warning or sign at all. If you have to 
> explicitly conform to the protocols, then your intention is clear, and if an 
> automatic implementation cannot be made (because not all members were 
> Equatable or Hashable), then you will get an error that you need to implement 
> the protocol yourself like you do now (i.e. implement == and hashValue).


…but I could’ve been clearer!

> 
>> 
>> On the one hand, it’s possible to imagine a finer-grained form of this 
>> synthesis that’d allow you to e.g. indicate a certain field should be 
>> omitted (and also perhaps specialize how fields are compared, customize the 
>> synthesized comparison ordering to put cheaper comparisons earlier, and an 
>> endless list of other possible requests…).
> 
> If you don’t trust the compiler to optimize this well and therefore want 
> control over order of comparisons you should probably just implement it 
> manually.  As you note below, this is a convenience feature that needs to 
> strike a fine balance.

I agree, but at the same time i think that scenarios like this:

  struct RevisionInfo {
let contentID: NSUUID
let revisionID: NSUUID
let contentData: NSData
  }

…aren’t going to be all that uncommon in practice; I think a good “layered” 
implementation of the derivation/synthesis logic would suffice (e.g. we 
wouldn't *need* special-case handling for ordering, potentially…).

> 
> IMO there are two issues involved:
> 
> 1. How do we invoke the automatic synthesis.
> 2. How do we have some degree of control over the synthesis that happens.
> 
> `deriving` addresses issue 1 and says nothing about issue 2.

Agreed here; 2 is the interesting question. If you look at my initial response 
in this thread I tried to suggest a “layered” approach:

Layer A: have some way of 

Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-27 Thread plx via swift-evolution

> On May 27, 2016, at 3:22 PM, Ricardo Parada via swift-evolution 
>  wrote:
> 
> Inline
> 
> 
> On May 27, 2016, at 2:52 PM, Matthew Johnson  > wrote:
> 
>> 
>>> On May 27, 2016, at 12:48 PM, Ricardo Parada >> > wrote:
>>> 
>>> 
>>> What if we get the error when trying to use it?  For example, if a struct 
>>> uses a value that is not Equatable / Hashable then it would not be 
>>> Equatable / Hashable and you would not find out until you tried to use it.  
>>> Would that be bad?
>> 
>> Yes.  It would also be bad if implicit synthesis resulted in an 
>> unintentional and incorrect definition of equality.  By requiring synthesis 
>> to be requested with `deriving` the programmer is at least prompted to 
>> consider the meaning of equality for their type.
> 
> Incorrect definition of equality? Hmm... :-)
> 
> I guess I have been running under the wrong assumption that if a struct uses 
> values that are all Equatable then the default implementation for the struct 
> which will compare the values against the values in the other struct will 
> ALWAYS be correct. But I guess I can come up with an example where some of 
> the values stored in the struct do not play a role in the definition of 
> equality even if those values are Equatable. Then the default implementation 
> would be incorrect. 

A recent one for me was a rational type, e.g. you’d want things like `1/2 == 
2/4` (and in this case I didn’t want an implementation that *would* always 
automatically use fully-reduced internal representations).

I *do* think Swift is missing a “bit-by-bit/physical" equality operator (for 
which 1/2 and 2/4 would be distinct, here), and Swift should probably get one 
at some point, but that’s IMHO another (but related) discussion.

> But I am not convince that is bad because   that can happen regardless of 
> whether equatable is an opt-in thing or automatic. For example, let's say you 
> opt-in by saying that it implements Equatable or by using the derived / 
> synthesizes keyword that we have mentioned. The developer may not realize 
> until later that the default implementation would be wrong for your 
> fancy/unusual struct.  It is likely that opting in may raise a flag in your 
> brain that says "hey, is the default implementation going to do the right 
> thing? Do you need to customize it for your struct?" But it's not a guarantee 
> either. And if it's not a guarantee then should it be automatic then? Most 
> developer will go with the default implementation when they opt-in and then 
> realize later that they may need to customize when things are not working 
> quite the way the expected. 
> 
> 
>>> 
>>> 
 On May 26, 2016, at 11:35 AM, Matthew Johnson via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
> 
> On May 26, 2016, at 10:18 AM, T.J. Usiyan via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> +1 to a `deriving` keyword
 
 + 1.  I like it as well.  It makes the feature opt-in, declaring 
 conformance and requesting synthesis at the same time.  The syntactic 
 difference from a simple conformance declaration means manual conformance 
 can still be checked properly with no ambiguity about whether you were 
 requesting synthesis or not.  This approach also generalizes well.
 
 This bullet makes me uncomfortable though:
 
> - It is compatible with generics. E.g. `struct Shape deriving 
> Equatable` will make every `Shape` equatable if `X` is equatable. But 
> if `X` is not equatable, `Shape` can be used as well. 
 
 
 You should not be able to just say `struct Shape deriving Equatable`.  
 You should have to do this:
 
 extension Shape deriving Equatable where T: Equatable {}
 
 Or some equivalent syntax that makes it clear that you only intend to 
 derive equatable when T meets the stated conditions.
 
> 
> On Thu, May 26, 2016 at 3:58 AM, Michael Peternell via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Can we just copy&paste the solution from Haskell instead of creating our 
> own? It's just better in every aspect. Deriving `Equatable` and 
> `Hashable` would become
> 
> struct Polygon deriving Equatable, Hashable {
> ...
> }
> 
> This has several advantages:
> - you don't have to guess wether `Equatable` or `Hashable` should be 
> automatically derived or not.
> - Deriving becomes an explicit choice.
> - If you need a custom `Equatable` implementation (for whatever reason), 
> you can still do it.
> - It doesn't break any code that is unaware of the change
> - It can be extended in future versions of Swift, without introducing any 
> new incompatibilities. For example, `CustomStringConvertible` could be 
> derived just as easily.
> - It is compatible with generics. E.g. `struct Shape d

Re: [swift-evolution] [Draft] Automatically deriving Equatable and Hashable for certain value types

2016-05-29 Thread plx via swift-evolution

> On May 29, 2016, at 9:22 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On May 29, 2016, at 9:12 AM, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>>> On 27.05.2016 18:37, plx via swift-evolution wrote:
>>> 
>>>> On May 26, 2016, at 1:00 PM, T.J. Usiyan via swift-evolution
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> A `deriving` keyword, at the very least, is pretty explicitly *not* an
>>>> all-or-nothing situation. If you want to define equality/hashability for
>>>> your type manually, don't use `deriving`. This should leave the simplest
>>>> cases to auto generation and anything more complex should be handled by
>>>> the developer.
>>> 
>>> It’s all-or-nothing in the sense you can’t use a naive `deriving`
>>> implementation to assist in any case where what you need is *almost* the
>>> trivial implementation, but not quite.
>> 
>> I support that we need a way to exclude some fields from participate in 
>> auto-derived code. It is not handy if we'll have just one-two excluded 
>> properties (of 10 for example) and we'll need to implement the boilerplate 
>> code because of this. Probably, this should be another proposal for this 
>> feature.
>> 
>> Just some thoughts: such a method to decorate some fields as 
>> `nonequatable`/`nonhashable` has no meaning *if* Equatable/Hashable is later 
>> implemented manually. So, to remove confusion, it seems like such 'method' 
>> to exclude should be disallowed(by compiler) if protocols are implemented 
>> manually by coder.
>> I.e., I don't want to see a code where we have *both* explicit 
>> implementations of protocols *and* some decorators/special functions to 
>> exclude some fields as this will no any sense.
>> 
>> Also for me it seems like we need to be able to define such attribute near 
>> the field itself, to prevent later errors when you define new field but 
>> forgot to add it to some 'special list' of excluded field somewhere in code.
>> So, probably I'd prefer some kind of @nonequatable and @nonhashable :
>> @nonequatable var field = 0
> 
> The same members should be considered by both Equatable and Hashable so there 
> would be no need for two separate annotations.  A more general annotation 
> (maybe "nonessential"?) is what we want.

I strongly disagree; IMHO the members considered for hashing *should* be a 
subset of those considered for equality (and “be the same” is a safe default).

As an example, I find I quite frequently wind up with types effectively like so:

struct ArticleContent {
  let articleID: NSUUID 
  let veryLongFullArticleContent: NSData // potentially huge, possibly slow
}

…for which, at least for the intended uses (and the intended data, etc.), 
hashing `articleID` is enough to get a well-behaved hash, and incorporating 
hashes of the other field(s) doesn’t have any apparent benefit.

> 
>> 
>> 
>>> 
>>> Consider a case like this:
>>> 
>>> class QuxEvaluator  {
>>> 
>>>   let foo: Foo // Equatable
>>>   let bar: Bar // Equatable
>>>   let baz: Baz // Equatable
>>> 
>>>   private var quxCache: [QuxIdentifier:Qux] // [Equatable:Equatable] = [:]
>>> 
>>>   // pure function of `foo`, `bar`, `baz`, and `identifier`
>>>   // expensive, and uses `quxCache` for memoization
>>>   func qux(for identifier: QuxIdentifier) -> Qux
>>> 
>>> }
>>> 
>>> …if it weren’t for `quxCache` we could easily synthesize `==` for
>>> `QuxEvaluator`, but the trivial synthesis will yield invalid results due to
>>> `[QuxIdentifier:Qux]` also being `Equatable` (really: it *will* also be
>>> equatable once conditional conformances are in place).
>>> 
>>> So we’re back to e.g. writing this:
>>> 
>>> extension QuxEvaluator : Equatable {
>>> 
>>> }
>>> 
>>> func ==(lhs: QuxEvaluator, rhs: QuxEvaluator) -> Bool {
>>>   return (lhs === rhs) || (lhs.foo == rhs.foo && lhs.bar == rhs.bar &&
>>> lhs.baz == rhs.baz)
>>> }
>>> 
>>> …just to omit a single field from the `==` consideration; this is another
>>> sense in which you can say deriving is an all-or-none; there’s just no way
>>> to invoke the synthesis mechanism other than for "all fields”.
>>> 
>>> On the one hand, it’s possible to imagine a finer-grained form of this
>>> synthesis that’d allow you to e.g. indicate a 

Re: [swift-evolution] Variadic generics discussion

2016-05-29 Thread plx via swift-evolution
Thanks for getting the discussion started with such a thorough initial writeup.

My overall concern is this:

- on the one hand, I *very much* understand—and support—the idea of starting 
simple and adding functionality later
- on the other hand, this is *already* a rather complicated proposal 
syntactically, semantically, and probably also in implementation
- on the gripping hand, I’m concerned that despite being so complicated, it’s 
perhaps too limited to pay for itself as-proposed

Or, put differently, if you believe there’s an optimal point on the 
complexity/functionality for a v1, I worry a bit after reading it that it’s 
buying too little practical functionality for the complexity it’ll bring, and 
that something a *little* more complex might provide a *lot* more practical 
utility.

To that end, I’ve provided some concrete-ish examples of things it’d be nice to 
be able to do via variadics and the additional features they would either 
*need* or at least *benefit* from having available. 

All of these are very much “nice to have” features that need not be included in 
a first version, but they each illustrate one possible complexity/capability 
trade-off.

A.1: Support for uniform variadic-parameter associated-type constraints?

Consider trying to write a variadic form of this sequence:

  // given sequences a, b, provides a sequence equivalent-to
  // zip(a,b).lazy.map() { 
  //   ( min($0.0,$0.1), max($0.0,$0.1) )
  // }
  struct ExtremaSequence {
private let a: A; private let b: B
  }

  struct ExtremaIterator {
private var a: A?
private var b: B?

mutating func next() -> (A.Element,A.Element)? {
  guard let nextA = a?.next() else {
a = nil; b = nil; 
return nil
  }
  guard let nextB = b?.next() else {
a = nil; b = nil; 
return nil
  }
  if nextA < nextB { 
return (nextA,nextB)
  } else {
return (nextB,nextA)
  }  
}

  }

…would it be necessary to write the type’s generic parameters like this:

  struct VariadicExtremaSequence

…or would there be some way of writing a constraint like “all `S.Iterator` must 
have same `.Element`?”?

A.2: Support for non-uniform "parameter-to-parameter” constraints

As an example:

  protocol ValueTransformer {
associatedtype Input
associatedtype Output
   
func transformedValue(for input: Input) throws -> Output

  }

  // how to express this (if possible), mock syntax below
  struct LoggingValueTransformerApplier<
T:ValueTransformer
where
…T[i],T[j]… => T[i].Output == T[j].Input> : ValueTransformer {

   typealias Input = #first(T…).Input
   typealias Output = #last(T…).Output

   private let (transformers) = (T...)

   func transformedValue(for input: Input) throws -> Output {
   // evaluate incrementally, logging input => (output | error) step-by-step
}

}

…something like the above is definitely a "nice to have", but not having it 
will close off certain use cases.

B: Integer-Based Indexing

I see it’s been brought up already, but I’d *strongly* suggest making support 
for integer-based “indexing” into variadic packs a priority.

What concerns me is that without support for that, I suspect a lot of code 
would have to get "written twice” if using the “recursive” API on parameter 
packs.

Here’s a mock example:
  
  // a “weaker” dictionary-like protocol
  protocol LookupTable {
associatedtype Key: Hashable
associatedtype Value

subscript(key: Key) -> Value? { get }

  }

  /// Does a cascading search for values through a possibly *heterogeneous*
  /// collection of backing lookup tables…caching results to avoid subsequent 
searches
  struct HeterogeneousCascadingLookupTable : LookupTable {

  private let (tables): (T…)
  private var valueCache: [K:V] = [:]
  private var missingKeys: Set = []

  // implementation *with* integer-based indexing: 
  subscript(key: K) -> V? {
get {
  guard !missingKeys.contains(key) else { return nil }
  if let cached = valueCache[key] { return cached }
  for index in 0..<#count(T…) {
 if let v = tables[index][key] {
   valueCache[key] = v
   return v
 }
  }
  missingKeys.insert(key)
  return nil
}
  }

  // implementation without integer-based indexing (or equivalent mechanism):
  subscript(key: K) -> V? {
get {
  guard !missingKeys.contains(key) else { return nil }
  if let cached = valueCache[key] { return cached }
  if let value = self.lookupValue(for: key, in: self.tables) {
valueCache[key] = value
return value
  } else {
missingKeys.insert(key)
return nil
  }
}
  }

  // recursive lookup implementation (necessary b/c our type itself
  // isn’t defined by recursively-nesting itself)
  private final func lookupValue(for key: K, in tables: U…) -> V? {
return #first(tables)[key] ?? self.lookupValue(for: key, in: #rest(tables))
  }

}

…which isn’t the end

Re: [swift-evolution] [Pitch] Property reflection

2016-05-29 Thread plx via swift-evolution
 both "statically typed" and runtime type 
> checked operations, when feasible, is a big one. I think something like 
> variadic generics could allow for typesafe reflection on methods and 
> functions at runtime - rather than having to call a performSelector: like 
> method, it would be possible to get a full-fledged value of function type and 
> use it just like any other method. This is something few languages have AFAIK.
> 
> The reflection machinery should cooperate with the rest of the language. If 
> there must be a way to, for example, access private members of an instance 
> through reflection, it should not be unconditional and should be carefully 
> considered such that there are certain invariants that are still honored. 
> Like Laurent said earlier, bad things can happen if you use reflection to 
> subvert access control.
> 
> I think reflection should be opt-in in most cases. Reflection opting-in 
> should be composable, inheritable, and retroactive, which covers the most 
> common cases in which reflection would be useful: working with Cocoa/Cocoa 
> Touch, for example.
> 
> Best,
> Austin
> 
> 
> 
>> On May 27, 2016, at 7:37 AM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> I think this proposal should “simmer" until we know what property behaviors 
>> will look like (or find out they are never happening, etc.). 
>> 
>> The interaction with “property behaviors” seems likely to be quite subtle, 
>> even for something simple like `lazy`.
>> 
>> For sake of argument, let’s say that a `lazy` declaration like so:
>> 
>>   class SomeClass { 
>> lazy var foo: Foo = Foo(bar: self.prepareBar())
>>   }
>> 
>> …gets implicitly-expanded into e.g. something like the below:
>> 
>>   class SomeClass {
>>  
>> var foo: Foo {
>>   guard let foo = _foo else {
>> _foo = Foo(bar: self.prepareBar())
>> return _foo
>>   }
>>   return foo
>> }
>> 
>> private var _foo: Foo? = nil
>> 
>>   }
>> 
>> …which immediately exposes a few lazy-specific questions:
>> 
>> - should `foo` be exposed via reflection? (IMHO: yes)
>> - should `_foo` be exposed via reflection? (IMHO: probably not, but not 
>> certain)
>> - should `foo`’s lazy-ness be exposable? (IMHO: yes, but how exactly?)
>> 
>> …as well as a few more-general questions:
>> 
>> - should computed properties, in general, be exposed to reflection? (IMHO: 
>> probably not, but there are some exceptions…)
>> - if user-specified property behaviors get special exposure, how should that 
>> work?
>> - how should reflection work for enums/enums-with-payloads? 
>> 
>> Finally, I worry a lot less about the details of getter/setter pairs than I 
>> worry about being able to use reflection for construction/initialization.
>> 
>> I don’t have any actual proposal on that front, but it seems like it should 
>> be factored into any reflection design.
>> 
>>> On May 26, 2016, at 8:25 PM, Austin Zheng via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Hi swift-evolution,
>>> 
>>> For those who are interested I'd like to present a pre-pre-proposal for 
>>> reflection upon a type's properties and solicit feedback. 
>>> 
>>> First of all, some caveats: this is only a very small piece of what 
>>> reflection in Swift might look like one day, and it's certainly not the 
>>> only possible design for such a feature. Reflection comes in many different 
>>> forms, and "no reflection" is also an option. Deciding what sort of 
>>> reflection capabilities Swift should support is a prerequisite to 
>>> stabilizing the runtime API, which I imagine has resilience consequences. 
>>> I'm not really interested in defending this specific proposal per se, as I 
>>> am looking for a jumping-off point to explore designs in this space.
>>> 
>>> Anyways, here is a gist outlining the public API to the feature: 
>>> 
>>> https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a 
>>> <https://gist.github.com/austinzheng/699d47f50899b88645f56964c0b7109a>
>>> 
>>> A couple of notes regarding the proposal:
>>> 
>>> The API names need improvement. Suggestions welcome.
>>> 
>>> It's opt-in: types have to conform to a special protocol for the compiler 
>>> to generate whatever hooks, metadata, and support code is necessa

Re: [swift-evolution] Variadic generics discussion

2016-05-30 Thread plx via swift-evolution
I’ll keep this quick since I see upthread you have already revised the proposal.

> On May 29, 2016, at 12:36 PM, Austin Zheng  wrote:
> 
>> …something like the above is definitely a "nice to have", but not having it 
>> will close off certain use cases.
> 
> Oh, this is interesting. So a way to specify an equality relationship between 
> "adjacent" sets of associated types?

Right, that was what I had in mind, and I can think of uses for such 
neighbor-to-neighbor type relationships.

There may be uses for other relationships—both beyond equality and beyond 
neighbor-to-neighbor—but I can’t think of any offhand.

One other pack-level constraint came to mind:

- can you enforce (T…) is *exactly* (T,T,T,…) N times? (e.g. T0 == T1, etc., 
not just "conforms to same protocols” or “have identical associated types”)

…along with some “pack-to-pack” constraints:

- if you have e.g. 2+ packs, can you enforce (T…) and (U…) have the same arity?
- if you have e.g. 2+ packs, could you enforce e.g. T.Foo… == U.Bar ?

…as always nice-to-have, but throwing them out there for consideration.

> I'll write something up.
> 
> for index in 0..<#count(T…) {
> if let v = tables[index][key] {
> valueCache[key] = v
>   return v
> }
> }
> 
> I assume this is all compile time code generation (unroll the loop in the 
> source #count(T...) times for each arity that T... is instantiated as, with a 
> different 'tables' pack member value for each unrolled loop iteration). 

I’d assume so too, but thinking it through I think it needs some alternative 
way of being expressed.

If you look @ the “obvious” implementation for the above as written, it unrolls 
into something like this:

  if let v = tables[0][key] { … } // assume returns out of here on success
  if let v = tables[1][key] { … } // assume returns out of here on success
  //…etc...

…but b/c tuples aren’t directly subscriptable, those `tables[index][key]` 
expressions themselves would perhaps get expanded into the equivalent of, e.g.:
 
  private func __subscriptTables(index index: Int, key: K) -> V? {
switch index {
   case 0: return tables.0[key]
   case 1: return tables.1[key]
   // etc...
   default: fatalError(“Invalid subscript into variadic…blah blah”)
}
  }

…and so the original expansion would be more like:

  if let v = __subscriptTables(index:0, key: key) { … } // assume returns out 
of here on success
  if let v = __subscriptTables(index:1, key: key) { … } // assume returns out 
of here on success
  //…etc...

….which repeats the switch at each line. In theory the optimizer can know to 
inline `__subscriptTables`, notice `index` is known at compile-time, replace 
the switch with direct access, and arrive at the code you “really want”:

  if let v = tables.0[key] { … } // assume returns out of here on success
  if let v = tables.1[key] { … } // assume returns out of here on success

…but that’s obviously putting a lot of pressure on the compiler to convert the 
`for index in #count(tables) { … }` code into something 
equivalent-but-reasonable.

I’ll be sure to look @ at the proposed `fold` in this light.

> This is interesting. Might it be possible with to accomplish this with 
> existentials (this is sort of a cross-reference to a different proposal from 
> the generics manifest)? An existential type as described below would work for 
> any pack where all the elements were constrained in the same way. Not sure if 
> it could be made to work in the case where the types in the pack are related 
> to each other (as proposed earlier).
> 
> struct ChainSequenceIterator 
> {
> 
>   // A single variable that contains each iterator in turn; specific type 
> doesn't matter as long as the element is E
>   private var iterator : Any?
> 
>   // ...
> } 

Actually yes, I hadn’t thought of that and you could make it work in this case 
(although perhaps with some indirection overhead? and it seems also with some 
additional state tracking to know which iterator you actually have).

Where I’m not as sure is for something like a `ChainCollectionIndex` (same 
`stuff from A, then stuff from B, etc” concept, but for A, B collections, and 
so on).

That’s more clearly a case where what you *want* ideally is something like this:

  struct ChainCollection2 {
let a: A; let b: B 
  }

  struct ChainCollectionIndex2 {
private var sourceIndex: Sum2 // e.g. (A | B)
  }

…since to implement the APIs you need A and A.Index and B and B.Index to "match 
up". It’s probably possible here to do something like this instead:

  struct ChainCollectionIndex2 {
private var boxedIndex: Box // actually either Box or Box
private var whichIndex: AOrB // (E.G. enum ilke IndexFromA | IndexFromB)
  }

…with a lot of casting and so on, and perhaps also with existentials (and/or 
casting and open-as), but it’d be *cleaner* with the sum, still.

Either way you’re right that e.g. existentials and similar + state flags can 
cover a lot of these 

Re: [swift-evolution] Variadic generics discussion

2016-05-30 Thread plx via swift-evolution
A few more comments inlined now that I’ve read it.

> On May 30, 2016, at 7:44 AM, plx via swift-evolution 
>  wrote:
> - if you have e.g. 2+ packs, can you enforce (T…) and (U…) have the same 
> arity?

Seems the answer is yes iff there’s a `T.Foo... == U.Bar…` style relationship, 
but no way to just request same-arity by itself?

> - if you have e.g. 2+ packs, could you enforce e.g. T.Foo… == U.Bar ?

Missed this either before or you added it, sorry either way.

> 
> …as always nice-to-have, but throwing them out there for consideration.
> 
>> I'll write something up.

I like the `fold` construct but feel like for this use it needs a few more 
options-or-variants.

The first one is some more-explicit support for “early exit”.

EG for the cascading-lookup example, you can convert it to this `#fold`:

  private func lookupKey(key: K) -> V? {
return #fold(
  start: nil,
  reducer: { 
(table, value)
in
return value ?? table[key]
  },
  values: tables
)
  }

…but unless the compiler is very savvy you are going to have a bunch of 
unneeded stuff even after your “success” (it won’t do another lookup, but it 
just seems wasteful and could be wasteful in other contexts).

Relatedly, that `#fold` is only going to work if the compiler can infer a 
proper type for the `table` argument to the `reducer`.

If you have to specify the types explicitly via a helper function, it seems 
like this won’t work:

  func lookupIfNecessary(table: 
T,  key: K, value: V?) -> V? {
 return value ?? table[key]
  }

…b/c the signature isn’t right for the reducer, and it seems like this might 
work:

  func createLookupFunction(key: 
K) -> (T, V?) -> V? {
 return { (t,v) in return v ?? t[key] }
  }

  private func lookupKey(key: K) -> V? {
return #fold(
  start: nil,
  reducer: createLookupFunction(key), // <- should work…I hope...
  values: tables
)
  }

…but it seems a bit convoluted; perhaps there’s a trick here? Or perhaps a 
variant with an adjusted signature like so:

  // perhaps inout K ? or as an option?
  #foldWithContext(context: K, start: U, reducer:(#requirements,U,K) -> U, 
values: (T…)) -> U

Relatedly, having `#fold` variants like the above that include the current 
index could address a lot of the uses for integer-based indexing:

  #indexedFold(start: U, reducer:(#requirements,U,Int) -> U, values: (T…)) -> U

…(the above can be done w/out dedicated support, but dedicated support might be 
more compiler-friendly on this one).

Finally, after reading it over again I really find the `…` confusing beyond the 
initial declaration sites (as you can perhaps tell since I’ve been mis-using it 
in my replies).

I can’t come up with an alternative that isn’t a major regression for simple 
declarations, but if a more-explicit syntax could be invented I’d highly prefer 
it.

>> 
>>> 
>>>> On May 28, 2016, at 3:03 PM, Austin Zheng via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Hello swift-evolution,
>>>> 
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <https://lists.swift.org/mailman/listinfo/swift-evolution>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Filter split extension on Sequence to return tuple of sequences that meet criteria and that do not

2016-06-09 Thread plx via swift-evolution
This reminds me of something: I *very* often wish the standard library had an 
analog to `NSIndexSet`.

I bring it up b/c it would allow, here, for IMHO a rather nice way to write the 
*eager* variant of this `filterSplit` (or preferably imho, `partition`, if not 
for the *other* `partition` out there) function:

  extension Collection {

/// Returns the index-sets upon which `predicate(self[$index])` evaluates 
to `true` and `false`, respectively, 
func partitionedIndices(predicate: (Element) -> Bool) -> 
(IndexSet, IndexSet)

  }

…from which—with a suitable IndexSet implementation!—it would then be easy to 
construct filtered views into the original collections (and even filtered 
collections, at least for e.g. range-replaceable collections).

It’d be nice to see such a type make it in at some point!

In the interim, a reasonable “primitive” it’d be nice to have in the standard 
library would be some methods like this:

  extension Collection {

 func classified(classifier: (Element) -> T) -> 
[(T,Range)]
 func lazilyClassified(classifier: (Element) -> T) -> 
LazyClassificationSequence

  }

…for which the semantics should be s.t. the below is a correct implementation 
of `filterSplit` (spelling them out more-precisely is doable but tedious):

  extension RangeReplaceableCollection {

func filterSplit(predicate: (Element) -> Bool) -> (Self,Self) {
  guard !self.isEmpty else { return (Self(), Self() }
  var trues: Self = Self()
  var falses: Self = Self()
  for (classification,range) in self.lazilyClassified(predicate) {
switch classification {
  case true: trues.appendContents(of: self[range])
  case false: falses.appendContents(of: self[range])
}
  }
  return (trues,falses)
}

  }

…which could also be generalized further (e.g. for T:Hashable, to then return 
`[T:Self]`, etc.).

Such “classification” methods would have broader-uses than implementing 
`filterSplit`; is there a specific reason something analogous isn’t already in 
the standard library (or shouldn’t be)?

Likewise, would an `IndexSet` type be something that could make it into the 
standard library at some point? (It'd have some API-design issues to sort out 
under collections-move-indices, but nothing that seems truly insurmountable.)

> On Jun 8, 2016, at 10:10 AM, gadiraju praneeth via swift-evolution 
>  wrote:
> 
> Many times, I came across a scenario where I had to filter an array with a 
> condition and filter the same array with opposite of that condition. For 
> example:
> 
> let values = [2, 4, 3, 5, 6, 9]
> 
> let divisibleByTwo = values.filter { $0 % 2 == 0 }
> let notDivisibleByTwo = values.filter { $0 % 2 != 0 }
> 
> Is there a way currently where we can filter the array into two arrays based 
> on a condition?
> 
> If not how about something like a filterSplit function where we get a tuple 
> of values:
> 
> values.filterSplit { $0 % 2 == 0 } = ([2,4,6], [3,5,9])
> 
> I have implemented this in our project and wanted to get your thoughts on it
> 
> ___
> 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] Retiring `where` from for-in loops

2016-06-12 Thread plx via swift-evolution

> On Jun 10, 2016, at 12:59 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Fri, Jun 10, 2016 at 12:30 PM, let var go  > wrote:
> I respect that anti-goal, but I think being over-rigid about limiting 
> developers' choice of expression is also an anti-goal.
> 
> To me, it is like guard statements vs. if-let statements. Some people find 
> one to be more clear than the other. Often times the best choice depends on 
> the context. Sometimes a guard statement can be re-written as an if-let 
> statement in a way that makes the code more clear, and vice versa.
> 
> The comparison with `guard` and `if` is a little inapt. The introduction of 
> `guard` solved a practical daily issue with `if` that was nicknamed the 
> pyramid of doom, where successive `if let` statements caused code to be 
> severely nested in braces and nearly unreadable. Further, you must exist the 
> scope with `guard`; thus, its use signals an intention not possible with 
> `if`. If, on the other hand, you do not wish to exit the scope, you must use 
> `if`. So in a Venn diagram, there are independent uses for `if` that cannot 
> be fulfilled by `guard`, and uses for `guard` that would be unreadable if 
> rewritten with `if`.
>  
> And different people will inevitably have different personal preferences - 
> their own "style", if you will - and will favor one over the other. But it 
> would be a mistake to force everyone into one box in order to prevent the 
> fracturing of the Swift community into "dialects."
> 
> But most importantly (and this is really the kicker for me) there are times 
> when the "where" syntax provides the maximum amount of clarity in the context 
> of my code, and I don't want to lose that expressive power.
> 
> This is the key and salient point here. Would you be able to share some 
> examples where the `where` syntax provides a clear win in clarity? That would 
> definitely be a huge pro, if it can be used to solve issues in expressiveness 
> much like `guard` allowed elimination of the pyramid of doom.

I’d hate to lose `where` in for-in loops; I use it a lot. My own 2c on it is 
that I think if you look at isolated uses of `where` it’s not adding much 
clarity, but having it can allow you to adopt more-consistent patterns 
overall…which IMHO *does* result in clearer code.

I’ll provide two examples of such “consistent patterns” and how the presence of 
`for`-`in` `where` helps stick with them.

First Pattern: for some simple types I like to do data-driven unit tests — 
here’s a collection of values to test, here’s a basic, “algebraic" property 
that should apply, test it actually does, and so on.

When I write a set of tests like that, I like to have a single variable holding 
the “instances to test” that is shared by all relevant tests; this lets me 
start with only a handful of values, confirm it seems to work, and then have a 
single place to edit once I’m ready to expand the values we test upon.

Such tests might wind up looking like this:

  func testNaiveAncestor() {
 // the root has no ancestor so we simply to skip it:
 for position in testPositions where !position.isRootPosition {
XCTAssertLessThan(
 position.naiveAncestor(), 
 position
)
 }
  }

  func testNaiveSuccessor() {
 for position in testPositions {
XCTAssertGreaterThan(
 position.naiveSuccessor(), 
 position
)
 }
  }

…where `testPositions` holds the values to test, and the two tests are each 
testing a basic algebraic property. Having `where` available on for-loops makes 
it possible to write these in such a way that the intended parallelism between 
the two is visually-apparent—you can tell they’re the same sort of thing just 
by looking at them—and it does so in a way that makes few assumptions on the 
type-or-contents of `testPositions`. 

So `where` here, IMHO, isn’t *clearly* clearer in `testNaiveAncestor()`, but it 
lets `testNaiveAncestor()` and `testNaiveSuccessor()` (etc.) be 
*systemically*-clearer, as it were.

Second Pattern: relatedly, I find code is much clearer when `guard` is 
only-ever used for early exits and early returns. 

There’s no requirement to *not* use `guard` and `continue` together, but if one 
is willing to stick to `guard` == “early exit / early return” it makes code 
much easier to read and audit.

In a handful of places I have for loops that would need both `continue`-style 
conditionals and also early-exit conditionals; having `where` means I can stick 
to using `guard` for early-exits, whereas without it I’d have extra nesting or 
mixed “early-exit” guard and “continue” guard. 

This is as short as I can make it:

  /// Returns the portion of our frame that *might* be visible on-screen; 
doesn't
  /// handle occlusion, but unlike `approximateWindowRegion` will account for 
  /// clipping done by our superviews.
  ///
  /// - note: `intersectionRegion(with view: UIView)` takes `self.bounds`, 
conve

Re: [swift-evolution] [Draft] Tuple-Based Compound Optional Binding

2016-06-12 Thread plx via swift-evolution
This proposal should specify if the tuple is evaluated “eagerly” or as an 
“early-exit”. 

That is, if we write `if let (foo,bar,baz) = (_foo(), _bar(), _baz())`, and 
_bar() -> nil, will `_baz()` have been evaluated, or not?

I’d use this feature either way, but the proposal should have a clear statement 
on this point.

> On Jun 12, 2016, at 6:46 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> When I suggested this syntax in the acceptance thread for SE-0099, Chris said 
> it should be written up as a proposal. I'm sure this will get lost in the 
> WWDC shuffle, but here goes.
> Tuple-Based Compound Optional Binding
> Proposal: TBD
> Author: Brent Royal-Gordon 
> Status: TBD
> Review manager: TBD
>  
> Introduction
> 
> This proposal enhances optional binding with a new, tuple-based syntax for 
> binding multiple values. It replaces functionality lost in SE-0099 with a 
> syntax compatible with the new design.
> 
> Swift Evolution Discussion: [Accepted with Revision] SE-0099 Restructuring 
> Condition Clauses 
> 
>  
> Motivation
> 
> In Swift 2, it was possible to bind multiple optional values in a single if 
> let, guard let, or while let clause:
> 
> guard let a = opt1, b = opt2, c = opt3 else { ... }
> SE-0099 
> 
>  simplified the syntax of conditional statements, but removed this feature so 
> that , could instead separate different conditional clauses. Code like this 
> must now use three separate optional binding clauses:
> 
> guard let a = opt1, let b = opt2, let c = opt3 else { ... }
> The similar case clause sidesteps this problem because it can pattern-match 
> tuples. Hence, you can put several patterns in a tuple on the left side of 
> the =, and a matching number of values in a tuple on the right side, and 
> match them all with one case clause:
> 
> guard case (.none, .none, .none) = (opt1, opt2, opt3) else { ... }
> This doesn't conflict with the clause separation syntax because the commas 
> are within parentheses. However, the analogous syntax for optional bindings 
> is not permitted:
> 
> guard let (a, b, c) = (opt1, opt2, opt3) else { ... }
> // error: initializer for conditional binding must have 
> // Optional type, not '(Int?, Int?, Int?)' (aka 
> // '(Optional, Optional, Optional)')
>  
> Proposed
>  Solution
> 
> We should extend optional binding clauses to permit a tuple of optional 
> values on the right of the = and a tuple of constants with identical arity on 
> the left. Swift should test each element of the tuple on the right, and if 
> none of them are nil, bind them to the constants on the left.
> 
> Nothing in this proposal should change the way optional binding handles an 
> optional tuple (T, U)?, as opposed to a tuple of optionals (T?, U?). Even an 
> optional tuple of optionals (T?, U?)? should continue to be handled as before.
> 
>  
> Detailed
>  Design
> 
> No change to the formal grammar is necessary, as the pattern and initializer 
> productions in the optional-binding-head rule can already match tuples:
> 
> optional-binding-head : 'let' pattern initializer
> Rather, Sema should be modified to detect this situation and generate 
> appropriate code. Currently, TypeCheckPattern.cpp essentially converts let a 
> = opt1 into case let a? = opt1; if this proposal is accepted, it should 
> similarly convert let (a, b) = (opt1, opt2) into case let (a?, b?) = (opt1, 
> opt2).
> 
>  
> Edge
>  cases
> 
>  
> Nested
>  tuples-of-optionals
> 
> Permitting deeper pattern matching of nested tuples is highly precedented by 
> pattern matching, but is a niche feature. It should be supported if easily 
> achievable.
> 
> guard let (a, (b, c)) = (opt1, (opt2, opt3)) else { ... }
>  
> Expressions
>  returning tuples of optionals
> 
> Ideally, optional bindings whose initializer is an expression evaluating to a 
> tuple of optionals would be supported:
> 
> let tuple = (opt1, opt2)
> if let (a, b) = tuple { ... }
> However, I'm not sure if Swift will have pinned down the type of the 
> initializer at the point where it's generating the pattern. If this would be 
> difficult or impossible to implement, Swift should continue to interpret code 
> like this as attempting to bind an opti

Re: [swift-evolution] [Pitch] Retiring `where` from for-in loops

2016-06-12 Thread plx via swift-evolution
> 
> First, notice how your comment is related to the `where` clause but is 
> actually sitting on top of the loop itself. Second, one of these two tests 
> visits every element while the other doesn't, and it took me three reads 
> before I could see that because I literally couldn't find the `where` clause 
> the first two times I scanned through your code. This is a false 
> "parallelism," causing the very thing that *isn't* parallel to disappear from 
> the reader's eye. Compare instead this alternative, which also flips the 
> boolean assertion:
> 
> ```
> func testNaiveAncestor() {
>   for position in testPositions {
> // the root has no ancestor
> if position.isRootPosition { continue }
> // (notice how I don't even have to comment that we're skipping root,
> // because the code says it explicitly for me)
> 
> XCTAssertLessThan(position.naiveAncestor(), position)
>   }
> }
> ```

Fair enough; I added the comment when posting here…the original didn’t have 
one, because the where clause also explicitly says we’re skipping that one. 

To me the parallelism I care about is the following paraphrase:

  for testItem in allRelevantPossibilities { someBasicPropertyHolds(testItem) }
  for testItem in allRelevantPossibilities { someOtherPropertyHolds(testItem) }

…and adding the logic to skip the irrelevant option into the definition of 
“allRelevantPossibilities” seems to do a better job preserving the structural 
similarity I care about than throwing in some ad-hoc looking imperative logic 
into the test logic itself (even though functionally both are equivalent).

> 
> Now, with my rewriting, the part of your test that is strictly similar to the 
> other test looks parallel, and the one part that isn't at all similar (the 
> skipping part) stands out explicitly and is now self-documenting code.
> 
> 
> So `where` here, IMHO, isn’t *clearly* clearer in `testNaiveAncestor()`, but 
> it lets `testNaiveAncestor()` and `testNaiveSuccessor()` (etc.) be 
> *systemically*-clearer, as it were.
> 
> Second Pattern: relatedly, I find code is much clearer when `guard` is 
> only-ever used for early exits and early returns. 
> 
> There’s no requirement to *not* use `guard` and `continue` together, but if 
> one is willing to stick to `guard` == “early exit / early return” it makes 
> code much easier to read and audit.
> 
> In a handful of places I have for loops that would need both `continue`-style 
> conditionals and also early-exit conditionals; having `where` means I can 
> stick to using `guard` for early-exits, whereas without it I’d have extra 
> nesting or mixed “early-exit” guard and “continue” guard. 
> 
> I don't know what to say here. The fact is that `guard` with `continue` is a 
> documented and advertised feature of Swift; it's not simply supported by 
> accident. Of course, you're free to choose not to use that feature at all. 
> And it is true that, currently, `where` allows you to avoid that feature at 
> the top of a `for` loop, but anywhere else inside the loop and you'll have to 
> deal with extra nesting if you choose to reject `guard` with `continue`.

The same is true of `where`, no? It’s a part of the language, documented, free 
to use or not to use when or if you find it helpful (or not).

In the same way you seem to have with `where` after a for-in — and would prefer 
to not have to check for it, etc. — I have a hard time following mixed 
break/continue/return usage, and prefer to not have to check the body of each 
guard clause’s `else` to figure out the control flow.

I can understand that you find that difficulty baffling; I find your 
difficulties `where` baffling, but can accept they are sincere.

> IIUC, one of the motivating reasons for introducing `guard` was to solve the 
> pyramid of doom problem. So you're rejecting the intended solution for extra 
> nesting, at least in certain circumstances, a choice you're obviously free to 
> make in your own code. But when it comes to designing a language for 
> everyone, the fact that some users reject the intended solution would be 
> grounds for re-examining that solution (i.e. `guard`), but the mantra here 
> has always been one solution where possible and not multiple. So this 
> certainly cannot be a justification for another feature (i.e. `where`) which 
> only incidentally provides a substitute solution in certain situations.

Personally I found this use of `where` completely unremarkable and something I 
never thought about until I saw this discussion gaining momentum; I was already 
used to similar constructs so it just seemed useful in a familiar and 
thoroughly-uninteresting way.

That said, I could get behind excising it if there was serious interest in 
eventually building-in something like LINQ or comprehensions (etc.); `where` 
after a for-in is at this point a bit of an odd duckling.

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

Re: [swift-evolution] [Pitch] Retiring `where` from for-in loops

2016-06-14 Thread plx via swift-evolution

> On Jun 13, 2016, at 10:26 AM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Jun 13, 2016, at 9:23 AM, let var go via swift-evolution 
>>  wrote:
>> 
>> I am 100% with Charlie on this. Expressiveness has to do with the 
>> *effectiveness* of conveying a thought or a feeling.
>> 
>> Keep "where". It is expressive. It conveys a specific idea effectively and 
>> concisely.
> 
> For those of you in favor of retaining `where`, how do you feel about adding 
> `while`, `until`, `unless`, etc?

In the interest of advancing the “what kind of language would I prefer swift 
become?”, here are my final thoughts on this topic:

For those particular keywords, I’d prefer having them (or equivalents). I’m not 
sure if I’d prefer having *all* of them—`where/unless` and `while/until`—or 
just one from each “pair”…I could go either way.

As a general consideration, I’d be in favor of having them b/c I’d really like 
Swift to have a comprehension-style construct (and associated syntax etc.).

Comprehension syntax is IMHO pretty common outside the C family—within the C 
family really only C# has something like it—and in general comprehension syntax 
has pretty similar structure from language to language. This link illustrates 
the syntax for 28 languages’  comprehension constructs, so it isn’t a bad 
overview:

https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(list_comprehension)

…(note that “comprehension syntax” isn’t quite the same thing as “list 
comprehensions”, but for “comparative syntax” purposes that link should be 
sufficient).

For me the appeal of “comprehension syntax” is that it allows writing code that 
feels more “semantic” than “mechanical”, and that paraphrases much closer to 
the intended meaning.

Here’s a toy example:

  // with a comprehension-like syntax
  // outside loop: “what items do we care about?"
  for visitor in queue where visitor.hasTicket until venue.isFull {
// inside loop: “…and what do we do with them?"
venue.admit(visitor)
  }

…which to my eyes paraphrases more-or-less how I’d describe what we’re doing:

- “keep admitting visitors with tickets until the venue is full”

…whereas without it, you get something like this:

  // without comprehension-style syntax
  // outside loop: where, mechanically, are we sourcing items from
  for visitor in queue {
// inside loop: muddled mix of filtering, app logic, and flow-control
// filtering:
guard visitor.hasTicket else { continue }
// app logic:
venue.admit(visitor)
// flow-control:
if venue.isFull { break }
  }

…which *is* closer to the underlying mechanics, but paraphrases more like 
something you'd see in a badly-translated 80s VCR programing manual:

- “Start considering visitors. If the visitor doesn't have a ticket, move on to 
the next visitor. Otherwise, admit the visitor. If the venue is full, stop 
considering visitors.”

Sure, they’re both equivalent—and even in the 80s, some people managed to 
program their VCRs!—but given the option I’d strongly prefer to write in the 
first style; I like having a clean segregation between “what items are of 
interest?” and “what do we do with them?”

So that’s what I like about comprehension-like constructs.

The current `for-in-where` is a bit of an anomaly; it could be grown into 
something a little richer—`for _ in _ where _ while _`  and/or `for _ in _ 
where _ until _` (etc.).—or it could be dropped and some better construct 
proposed.

But, my personal preference would be to keep it around until either the richer 
construct is available or definitively declared as “not swift-y, not 
happening”: 

- if a “comprehension” construct is approved, an automatic migrator would 
likely do a *much* better job translating those `for _ in _ where` loops than 
it’d do with their more-imperative equivalents
- if a “comprehension” construct is definitively-rejected, at least I can keep 
using something I like until the hammer drops

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

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


Re: [swift-evolution] [Proposal] Generic and `throw`ing subscripts

2016-06-22 Thread plx via swift-evolution
Prefacing the below with a “I am well-aware this proposal likely won’t make it 
into Swift 3”:

A feature like this would be nice to use, but before I could get behind any 
proposal along these lines it I’d want to see it include an explicit strategy 
for disambiguation.

EG: in your example, your generic subscript uses `self[key]`, and presumably 
expects that to use the “original” subscript…and not the generic subscript 
being defined.

I think that’s reasonable in that specific case, but it doesn’t seem 
unreasonable to anticipate this proposal introducing ambiguities that would 
need explicit disambiguation…and for which explicit type annotation may not 
always be adequate to resolve (I could be wrong here, though). 

This would need addressing (either showing they won’t be an issue, or providing 
a reliable disambiguation mechanism).

Relatedly, in-re: “rethrows”: if the syntax supported it, this kind of thing 
would be another way of tackling the "JSON problem":

  subscript(key: Key, transform: (Value) throws -> T) rethrows -> T {
guard let value = self[key] else { throw JSON.MissingKey(…) }
return try transform(value)
  }

…so that e.g. you can write typical parsing-code as

  let asUserID = UserID.init(untrustedString:) // <- assume this is a "throwing 
constructor"
  let sender = try json[“sender”,asUserID] 
  let recipient = try json[“recipient”,asUserID]

…(modulo any syntax errors, etc.), which would benefit from a `rethrows` 
declaration.

That’s my 2c; thankfully (IMHO) there’s clearly a lot of time for this proposal 
to simmer.

> On Jun 20, 2016, at 1:10 PM, Robert Widmann via swift-evolution 
>  wrote:
> 
> Good morning all.  Attached is the proposal Harlan Haskins and I will be 
> submitting shortly about adding generic and `throw`ing subscript declarations 
> to the language.  
> 
> Cheers,
> 
> ~Robert Widmann
> 
> Generic and Throwing Subscripts
> 
> Proposal: SE- 
> 
> Author(s): Harlan Haskins  and Robert 
> Widmann 
> Status: Awaiting review 
> 
> Review manager: TBD
> Introduction
> 
> Currently, subscripts cannot be declared [re]throws and cannot declare new 
> generic parameters.
> There isn't a clear reason why they aren't as capable as full-fledged 
> functions, so we propose
> adding generic constraints and throwing semantics to subscripts.
> 
> Motivation
> 
> On the throwing side, currently there are two ways to express a failing 
> subscript:
> 
> Return an Optional, failing with nil.
> Call fatalError(_:) on failure.
> Both of these throw out useful information about the cause of the underlying 
> error that using Swift's error handling mechanism can otherwise provide.
> 
> As for generics, to take an example, it has become a common pattern among 
> JSON decoding DSL libraries to express a throwing generic extension on 
> Dictionary like so
> 
> extension Dictionary {
> public func parse(key: Key) throws -> T {
> guard let value = self[key] else {
> throw JSONError.MissingKey("\(key)")
> }
> guard let ofType = value as? T else {
> throw JSONError.InvalidKey(key: "\(key)", expectedType: T.self, 
> foundType: value.dynamicType)
> }
> return ofType
> }
> }
> 
> public enum JSONError: ErrorType, CustomStringConvertible {
> case InvalidKey(key: String, expectedType: Any.Type, foundType: Any.Type)
> case MissingKey(String)
> public var description: String {
> switch self {
> case .InvalidKey(let key, let expected, let found):
> return "Invalid key \"\(key)\". Expected value of type 
> \"\(expected)\", found \"\(found)\"."
> case .MissingKey(let key):
> return "Key \(key) not found."
> }
> }
> }
> Given this, one can decode JSON with the full support of native type 
> inference and exception handling. But when working with the DSL, one would 
> expect to be able to express this as a subscript on Dictionary, allowing the 
> following:
> 
> //...
> 
> extension Dictionary {
> public subscript(key: Key) throws -> T {
> guard let value = self[key] else {
> throw JSONError.MissingKey("\(key)")
> }
> guard let ofType = value as? T else {
> throw JSONError.InvalidKey(key: "\(key)", expectedType: T.self, 
> foundType: value.dynamicType)
> }
> return ofType
> }
> }
> We believe this is an even more natural way to write these kinds of libraries 
> in Swift and that bringing subscript member declarations up to par with 
> functions is a useful addition to the language as a whole.
> 
> Proposed solution
> 
> Add the ability to introduce new generic parameters and mark throws and 
> rethrows on subscript members.
> 
> Detailed design
> 
> This change will modify and add the 

Re: [swift-evolution] [Proposal] Generic and `throw`ing subscripts

2016-06-22 Thread plx via swift-evolution

> On Jun 22, 2016, at 8:28 AM, T.J. Usiyan  wrote:
> 
> plx: wouldn't the same overload resolution strategy be appropriate here? 
> "most specific choice, otherwise diagnostic”

I’d assume it’d be good enough for most cases, certainly; I’d love to turn out 
to be needlessly scaremongering here, too.

But (hopefully unintentionally!) it seems like you could easily wind up with 
scenarios like this:

  // from proposal:
  public subscript(key: Key) throws -> T {
guard let value = self[key] else { throw ... }
guard let ofType = value as? T else { throw ... }
return ofType
  }

  // an annoying addition:
  public subscript(key: Key) throws -> T {
guard let v = self[key] else { throw ... }
guard let rawValue = v as? T.RawValue else { throw ... }
guard let converted = T(rawValue: rawValue) else { throw ... }
return converted
  }

  // assume `Foo:RawRepresentable`:
  let foo: Foo = json["foo"]

…and similar, where I’d assume the `T:RawRepresentable` would “win”, but I’m 
not sure *how* you could force use of the *other* subscript in the above.

This isn’t really a new problem, but it seems likelier to be encountered if 
generic subscripts become allowed, due to all subscripts having the same “name”.

But again I’d like to be wrong about the issue (or at least the severity).

> 
> separately:
> Are there any subscripts in the standard library that would be 
> throwing/generic but can't be?
> 
> 
> On Wed, Jun 22, 2016 at 9:13 AM, plx via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> Prefacing the below with a “I am well-aware this proposal likely won’t make 
> it into Swift 3”:
> 
> A feature like this would be nice to use, but before I could get behind any 
> proposal along these lines it I’d want to see it include an explicit strategy 
> for disambiguation.
> 
> EG: in your example, your generic subscript uses `self[key]`, and presumably 
> expects that to use the “original” subscript…and not the generic subscript 
> being defined.
> 
> I think that’s reasonable in that specific case, but it doesn’t seem 
> unreasonable to anticipate this proposal introducing ambiguities that would 
> need explicit disambiguation…and for which explicit type annotation may not 
> always be adequate to resolve (I could be wrong here, though). 
> 
> This would need addressing (either showing they won’t be an issue, or 
> providing a reliable disambiguation mechanism).
> 
> Relatedly, in-re: “rethrows”: if the syntax supported it, this kind of thing 
> would be another way of tackling the "JSON problem":
> 
>   subscript(key: Key, transform: (Value) throws -> T) rethrows -> T {
> guard let value = self[key] else { throw JSON.MissingKey(…) }
> return try transform(value)
>   }
> 
> …so that e.g. you can write typical parsing-code as
> 
>   let asUserID = UserID.init(untrustedString:) // <- assume this is a 
> "throwing constructor"
>   let sender = try json[“sender”,asUserID] 
>   let recipient = try json[“recipient”,asUserID]
> 
> …(modulo any syntax errors, etc.), which would benefit from a `rethrows` 
> declaration.
> 
> That’s my 2c; thankfully (IMHO) there’s clearly a lot of time for this 
> proposal to simmer.
> 
>> On Jun 20, 2016, at 1:10 PM, Robert Widmann via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Good morning all.  Attached is the proposal Harlan Haskins and I will be 
>> submitting shortly about adding generic and `throw`ing subscript 
>> declarations to the language.  
>> 
>> Cheers,
>> 
>> ~Robert Widmann
>> 
>> Generic and Throwing Subscripts
>> 
>> Proposal: SE- 
>> <https://github.com/apple/swift-evolution/blob/master/proposals/-name.md>
>> Author(s): Harlan Haskins <https://github.com/harlanhaskins> and Robert 
>> Widmann <https://github.com/codafi>
>> Status: Awaiting review 
>> <https://github.com/typelift/SwiftCheck/pull/168#rationale>
>> Review manager: TBD
>> Introduction
>> 
>> Currently, subscripts cannot be declared [re]throws and cannot declare new 
>> generic parameters.
>> There isn't a clear reason why they aren't as capable as full-fledged 
>> functions, so we propose
>> adding generic constraints and throwing semantics to subscripts.
>> 
>> Motivation
>> 
>> On the throwing side, currently there are two ways to express a failing 
>> subscript:
>> 
>> Return an Optional, failing with nil.
>> Call fatalError(_:) on failure.
>> Both of these throw out useful information about the cause of the underlying 
>> error that using Swift'

Re: [swift-evolution] [Proposal] Generic and `throw`ing subscripts

2016-06-22 Thread plx via swift-evolution
You’re right on the specifics, of course.

To be clear I am more concerned about accidental shadowing with such 
subscripts; picture starting initial development with only the generic 
subscript from the proposal, writing some code that uses it…and then at some 
later point in time importing a module that defines the `RawRepresentable` 
variant, which would subtly shift how your code got interpreted.

This isn’t anything that couldn’t happen today with plain-old functions, of 
course — and it can be worked around in various ways, if you know it happens — 
but given the IMHO much higher likelihood of "name collisions” (you’re correct 
you can label the subscript arguments, but I doubt most subscripts will opt to 
do so)…it seems far likelier we’ll see resolution-modifying collisions under a 
proposal like this, should it be introduced.

But I could be very wrong, and in any case this proposal should probably wait 
until at least August, as per suggestion.

> On Jun 22, 2016, at 9:29 AM, Matthew Johnson  wrote:
> 
>> 
>> On Jun 22, 2016, at 9:11 AM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>>> On Jun 22, 2016, at 8:28 AM, T.J. Usiyan >> <mailto:griotsp...@gmail.com>> wrote:
>>> 
>>> plx: wouldn't the same overload resolution strategy be appropriate here? 
>>> "most specific choice, otherwise diagnostic”
>> 
>> I’d assume it’d be good enough for most cases, certainly; I’d love to turn 
>> out to be needlessly scaremongering here, too.
>> 
>> But (hopefully unintentionally!) it seems like you could easily wind up with 
>> scenarios like this:
>> 
>>   // from proposal:
>>   public subscript(key: Key) throws -> T {
>> guard let value = self[key] else { throw ... }
>> guard let ofType = value as? T else { throw ... }
>> return ofType
>>   }
>> 
>>   // an annoying addition:
>>   public subscript(key: Key) throws -> T {
>> guard let v = self[key] else { throw ... }
>> guard let rawValue = v as? T.RawValue else { throw ... }
>> guard let converted = T(rawValue: rawValue) else { throw ... }
>> return converted
>>   }
>> 
>>   // assume `Foo:RawRepresentable`:
>>   let foo: Foo = json["foo"]
>> 
>> …and similar, where I’d assume the `T:RawRepresentable` would “win”, but I’m 
>> not sure *how* you could force use of the *other* subscript in the above.
>> 
>> This isn’t really a new problem, but it seems likelier to be encountered if 
>> generic subscripts become allowed, due to all subscripts having the same 
>> “name”.
> 
> This isn’t exactly true.  External argument labels are considered part of the 
> “name” in Swift.  Subscripts parameters don’t get external labels 
> automatically like other functions / methods do, but you can still add one if 
> you *want* the ability to disambiguate.  
> 
> Of course this won’t help if you require the ability to use both subscripts 
> without a label but is worth noting.  It is also worth noting that this 
> behavior is no different from that of any other function or method - if the 
> name (including external argument labels) matches the most specific overload 
> will always be selected.
> 
> One way to make your example work properly when `T` is `RawRepresentable` and 
> the dictionary actually contains an instance of `T` is to add an extra check 
> for that case:
> 
>   public subscript(key: Key) throws -> T {
> guard let v = self[key] else { throw … }
> 
> // extra check here in case the value is *already* T and therefore does 
> not require conversion.
> if let value = v as? T { return value }
> 
> guard let rawValue = v as? T.RawValue else { throw ... }
> guard let converted = T(rawValue: rawValue) else { throw ... }
> return converted
>   }
> 
>> 
>> But again I’d like to be wrong about the issue (or at least the severity).
>> 
>>> 
>>> separately:
>>> Are there any subscripts in the standard library that would be 
>>> throwing/generic but can't be?
>>> 
>>> 
>>> On Wed, Jun 22, 2016 at 9:13 AM, plx via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> Prefacing the below with a “I am well-aware this proposal likely won’t make 
>>> it into Swift 3”:
>>> 
>>> A feature like this would be nice to use, but before I could get behind any 
>>> proposal along these lines it I’d want to see it include an explicit 
>>> strategy for disambiguation.
>>> 
>>> EG: in your example, your generic subscript u

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

2016-06-24 Thread plx via swift-evolution
+1; I *really* appreciate taking a proactive approach to eliminating future 
sources of bizarre “gotcha” moments!

> On Jun 23, 2016, at 2:53 PM, Slava Pestov via swift-evolution 
>  wrote:
> 
> Consistent formal type for 'self' in class methods
> 
> Proposal: SE- 
> 
> Author: Slava Pestov 
> Status: Awaiting review
> Review manager: TBD
> 
>  
> Introduction
> 
> This proposal makes the self value behave consistently whether or not it is 
> used from a method with a Self return type.
> 
> Swift-evolution thread: Discussion thread topic for that proposal 
> 
>  
> Motivation
> 
> Right now, we exhibit inconsistent behavior when self is used as an argument 
> to a generic function, violating the principle of least surprise.
> 
> Consider the following code:
> 
> class Base {
>   @discardableResult
>   func methodWithDynamicSelf() -> Self {
> doSomething(self)
> return self
>   }
> 
>   func methodWithoutDynamicSelf() {
> doSomething(self)
>   }
> }
> 
> class Derived : Base {}
> 
> func doSomething(_ t: T) {
>   print(T.self)
> }
> 
> Base().methodWithDynamicSelf()
> Base().methodWithoutDynamicSelf()
> 
> Derived().methodWithDynamicSelf()
> Derived().methodWithoutDynamicSelf()
> Currently, it prints the following output:
> 
> Base
> Base
> Derived
> Base
> Note that there's no inconsistency when the method is called on the base 
> class. When called on the derived class however, we see that in a method with 
> a dynamic Self return type, the type of self is Derived, whereas in a method 
> with any other return type, the type of self is Base.
> 
> 
>  
> Proposed
>  solution
> 
> The proposal is to change the type of self to always be Self, which can be 
> thought of as a special generic type parameter bound to the dynamic type of 
> the instance.
> 
> With this proposal, the above code will instead produce the following:
> 
> Base
> Base
> Derived
> Derived
> Here, the type of self would always be Derived when called on an instance of 
> the derived class.
> 
> Of course a more useful program could instead do something with the type 
> parameter T, such as constraining it to a protocol or a class with a required 
> initializer, and then using the type to construct a new instance of the class.
> 
> This also dovetails nicely with SE-0068 
> .
> 
> Finally, it opens the door to generalizing dynamic Self, allowing it to 
> appear in covariant position within parameter types:
> 
> class ArtClass {
>   func paint(withBrush: (Self) -> ()) { ... }
> }
> This would allow a class to conform to a protocol with a requirement written 
> like the following, something that is currently not possible at all:
> 
> protocol OddProtocol {
>   func weaken((Self) -> (X) -> Y) -> (X) -> Y
> }
> 
>  
> Detailed
>  design
> 
> There's really not much more to say here. The code for typing self with a 
> dynamic Self is in place already, however enabling this change might expose 
> some new bugs we have not yet encountered, because currently, methods with 
> dynamic Self return type are relatively rare.
> 
> 
>  
> Impact
>  on existing code
> 
> This will have a small impact on existing code that uses a pattern similar to 
> the above.
> 
> 
>  
> Alternatives
>  considered
> 
> One alternative is to simply do nothing, but this makes the language less 
> consistent than it could be.
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0105: Removing Where Clauses from For-In Loops

2016-06-24 Thread plx via swift-evolution
-1 for the reasons already brought up. 

I would also point out that half the biasing argument is extremely 
questionable: yes, for-in-where is “biased” in favor of “visit-if” and not 
"visit-unless”, but this form of “bias” is inevitable unless you start 
multiplying keywords (to have one for each “polarity”).

Note that, e.g., `guard` is also biased in a particular direction — we have 
`guard $conditionThatMustBeTrue` but not `unless 
$conditionThatShouldNotBeFalse` — and although this choice *does* make sense 
(due to let-binding being a success-case), it *is* otherwise backwards from 
traditional guard clauses (which were usually `if $exitCondition { $exit }`, 
which is the opposite polarity from how `guard` works).

So unless you want to have 2 of every control-flow keyword, whenever you have 
just one of each you just have to learn the “polarity" of each…this seems 
inevitable. Also note that even if you *did* go for 2-of-each, picking names 
that are sufficiently self-evident is harder than it looks, so in practice 
you’d almost certainly still have to wind up learning at least one of them, if 
not both.

Additionally, I would point `for-in-where` has some unique aspects that would 
complicate taking the “remove today to improve tomorrow” approach (as has been 
done with some other features like splatting).

Specifically, using for-in-where is a stylistic decision, and although 
translating its uses *to* `guard-continue` form can be done mechanically, 
translating `guard-continue` *back* to the (successor of) `for-in-where` in a 
stylistically-appropriate way seems much harder to mechanize…so if it was 
dropped for later, improved reinstatement, the temporary dropping might result 
in losing a lot of the original human stylistic choice, which IMHO is useful 
evidence of the original human intent.

> On Jun 22, 2016, at 11:12 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0105: Removing Where Clauses from For-In Loops" begins now 
> and runs through June 29. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0105-remove-where-from-forin-loops.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0104: Protocol-oriented integers

2016-06-24 Thread plx via swift-evolution
+1 but with a few reservations.

# Arithmetic

What *are* the expected semantics of the operators? It seems like you can’t 
assume much about a generic `Arithmetic` type, e.g. in a generic context I 
can’t reliably assume even things like these:

- `(x / y) * y == x` (or even “is close to" x) 
- `(x + x + … + x) / n ==  x` (for `x` added together `n` times)
- `((x + y) + z) == (x + (y + z))` (etc.)
- `(x + y) - y == x`(? I think...)

…and so on; am I missing something? 

If `Arithmetic` is as lacking in semantics as it seems, then it feels like one 
of those “bag of syntax” protocols that keep getting mentioned as against the 
stdlib philosophy.

# More Bit Operations

These don’t have to go into a v1, but I’d like to request seriously considering 
baking good support for things like popcount  first set bit, etc., directly 
into the appropriate protocol (`FixedWidthInteger`?).

I won’t pretend there are specific generic algorithms simply waiting on their 
presence or anything…it just seems like a logical extension of the rationalized 
bit-shifting behavior in the proposal (and at least IMHO things like popcount 
really ought to have been fundamental operations on par with the shifts and 
bitwise operations, but that’s an aside).

# Endianness & Byte-Reversal

Endianness seems entirely unaddressed. I assume it’s intentional and, if so, I 
agree it’s *mostly* best omitted...but I’m curious if there’s already a plan 
for addressing that at this level or not? Even if just including a function 
like `func byteReversed() -> Self` (etc.) on a suitable protocol (e.g. 
`FixedWidthInteger`, or perhaps a new refinement thereof?). 

I think that’s it for now. Overall I like it!

> On Jun 22, 2016, at 7:52 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0104: Protocol-oriented integers" begins now and runs 
> through June 27. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [RFC] New collections model: collections advance indices

2016-04-08 Thread plx via swift-evolution

> On Mar 8, 2016, at 11:49 AM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> on Tue Mar 08 2016, plx  > wrote:
> 
>>> On Mar 3, 2016, at 3:28 PM, Dmitri Gribenko 
>>> wrote:
>> 
>> I think it’s possible to adjust the protocol hierarchy to “reserve
>> room”—remove `Indexable`’s methods from `Collection`, add them back to
>> a new `ForwardCollection` between `Collection` and
>> `BidirectionalCollection`—but it’d only make sense to do that if you
>> expect to have use for that room in the future.
> 
> This is something we expressly don't do in generic programming.
> Protocols (concepts) are spawned only by the existence of real-world
> use-cases, and enough of them to make the generality worthwhile.

Apologies for the long delay in replying. I’ll keep this somewhat brief b/c:

- it’s been almost a month
- it’s perfectly-feasible for me to tack-on my own little hierarchy for my own 
needs, if necessary

…so even though I would personally *prefer* that `Collection` be defined as 
*having-a* canonical linearization (as opposed to *being-a* linearization), it 
doesn't seem to be of pressing concern.

I do, however, have an alternative proposal: would it be possible to have 
`Collection` support some methods like these (but with less-atrocious naming):

  // MARK: Basic “Unordered” Iteration

  /// Like `forEach`, but need not *necessarily* visit elements in the same 
order as you would
  /// see them in a for-in loop; meant for use for when all you need is to 
visit each element in *some* order.
  func unorderedForEach(@noescape visitor: (Self.Generator.Element) throws -> 
Void) rethrows

  /// Type of the sequence for `unorderedElements`; a default that is `== Self` 
seems reasonable.
  associatedtype UnorderedElementSequence: Sequence where 
UnorderedElementSequence.Generator.Element == Self.Generator.Element

  /// Returns a sequence that visits all elements in `self` in *some* order, 
but not
  /// necessarily the same order as a for-in loop (and not *necessarily* the 
same
  /// ordering as-in `unorderedForEach`…)
  func unorderedElements() -> UnorderedElementSequence

…and perhaps also some methods like these:

  // MARK: “Unordered” Enumeration (Index + Element)

  /// Like `unorderedForEach`, but the closure is given `(indexOfElement, 
element)` rather than
  /// just `element` itself; the name here is terrible in particular. No 
guarantee the ordering is
  /// the same as the ordering for unorderedForEach
  func unorderedEnumeratedForEach(@noescape visitor: 
(Self.Index,Self.Generator.Element) throws -> Void) rethrows

  /// Type of the sequence for `unorderedEnumeration `; a default that is 
identical to what `self.enumerate()` returns seems reasonable.
  associatedtype UnorderedEnumerationSequence: Sequence where 
UnorderedElementSequence.Generator.Element == 
(Self.Index,Self.Generator.Element)

  /// Returns a sequence that visits all pairs of `(indexOfElement, element) in 
`self` in *some* order, but not
  /// necessarily the same order as a for-in loop.
  func unorderedEnumeration() -> UnorderedEnumerationSequence

…?

If you want a motivating example, suppose you have a k-ary tree-like 
implemented as a packed array (in the usual way).

Obviously the “standard” for-in/index/etc. iteration should respect the “tree 
ordering”; but, if all you’re doing is this:

  // or `for view in contentViews`...
  contentViews.forEach() { $0.hidden = false }

…it’d be nice to be able to write something like this:

  // or `for view in contentViews.unorderedElements()`...
  contentViews.unorderedForEach() { $0.hidden = false } 

…to avoid paying the cost of visiting things in order?

For concrete types you can always define such methods and call them when 
appropriate, but I think it’d be very handy to have such methods available in 
generic contexts.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0062: Referencing Objective-C key-paths

2016-04-08 Thread plx via swift-evolution
> What is your evaluation of the proposal?
I like it and think it’s something Swift should definitely have.

A quibble: I think there’d be value in also having:

   #key(ClassName.propertyName)

…which is the same as `#keyPath`, but without support for *paths*.

It’s functionally-redundant with the more-general #keyPath but makes intent 
clearer, and is IMHO both shorter and clearer at any call-site that require 
keys, not key-paths.

> Is the problem being addressed significant enough to warrant a change to 
> Swift?
Yes for the same reasons #selector was added.

> Does this proposal fit well with the feel and direction of Swift?
Yes.

> If you have used other languages or libraries with a similar feature, how do 
> you feel that this proposal compares to those?
> How much effort did you put into your review? A glance, a quick reading, or 
> an in-depth study?
Quick read, didn’t follow the lead-up discussion.

> More information about the Swift evolution process is available at
> 
> https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> Thank you,
> 
> -Doug Gregor
> 
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-12 Thread plx via swift-evolution
Aside: `indices` being irregular can be a benefit in the context of 
auto-complete.

>   * What is your evaluation of the proposal?

+1, very much.

As a change from the current model, it’s an across-the-board improvement for 
me, at least.

In a bigger-picture sense I think Swift would be better off by going *further* 
on certain aspects, but have said all that before.

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

It is, again very much so.

>   * Does this proposal fit well with the feel and direction of Swift?

Depends on the framing of the question.

Compared to the previous model, it’s an unqualified YES.

As a general proposition, I think this design is a local optimum for overall 
Swift-ness, but even so it’s creating a little un-Swifty pocket. It’s 
“un-Swifty” in at least two ways:

# 1: Relatively Unsafe, Pointer-Like Semantics

Indices—unsurprisingly!—behave quite a bit like pointers, and similarly expose 
*numerous* crashing combinations of `(value,operation)`:

- self[endIndex]
- self[startIndex] // <- when empty
- successor(of: endIndex)
- predecessor(of: startIndex)

…etc., which is *very much* reminiscent of the hazards of pointers. 
(Technically “undefined” not “crashing”, but being realistic “crashing" is 
usually accurate).

Although Swift uses `Optional` to mitigate the hazards of `nil` pointers 
(etc.), you’re still left to your own devices for handling indices.

This isn’t news to anyone here, I’m sure, and may even be unavoidable; I’m just 
pointing it out as an uncharacteristically-unsafe area in Swift’s standard 
APIs, and closer to how `!` and IOUs behave than otherwise typical.

To help illustrate the claim, here’s a strawman “safe” API—for illustration 
only, not advocacy!—that would be safer and thus perhaps more “Swift-y”:

  protocol SafeCollection {

/// `Index` by another name
associatedtype Position: Equatable // , Comparable too if you want
  
/// Returns `nil` when empty. A non-strawman version
/// would return something better than a labeled tuple, here.
var bounds: (first: Position, last: Position)? { get }
  
/// Returns the first position, or `nil` when empty. 
/// Like `startIndex` but any non-nil value is safe to subscript.
var firstPosition: Position? { get }

/// Returns the last position, or `nil` when empty. 
/// Like `endIndex` but any non-nil value is safe to subscript.
var lastPosition: Position? { get }
  
/// No risk of trying to subscript `endIndex` here.
subscript(position: Position) -> Element
  
/// Safe to call on any non-nil position from this collection;
/// no risk of trying to advance the `endIndex` here.
func successor(of p: Position) -> Position?

/// Safe to call on any non-nil position from this collection;
/// no risk of trying to retreat-from the `startIndex` here.
func predecessor(of p: Position) -> Position?

// and so on and so forth

  }

…which, again, I include for purpose of *comparison* only. I *believe* this 
illustration has more of the “index-safety” Brent is getting at, but I can’t 
speak for him.

Pros:
- safer, b/c there’s no `nil`-analog like `endIndex` that needs checking-for
- feels more Swift-like (safer, harder to mis-use)

Cons:
- likely less-efficient than current proposal
- wants you to use closed index ranges, not half-open
- doesn’t address index-invalidation (discussed immediately below)

So, again, I’m not advocating that “safer” design be Swift's basic 
building-block, but I think it illustrates why it’s fair to call the index 
system relatively “unsafe”: as proposed, indices have semantics that are 
lower-level than they seem, with a safety profile *closer to* IOU/`!` than most 
of Swift’s standard library. 

# 2: Index Invalidation Unrepresented In Type System 

A related “un-Swift-y” aspect is that index-invalidation has no type-level 
representation whatsoever. Some operations on collections invalidate indices, 
but which operations? Which indices?

I don’t have a proposed *solution* I feel good about as to how to represent 
invalidation in the type system, but even so “values that become invalid for 
further use due to actions that happen elsewhere” is not very Swift-y.

# Remarks

Don’t get me wrong, I still like this proposal, and am *very* skeptical that 
something like the “safer index” sketched above would be a net win; I just 
think it’s very fair to say that indices are a corner of the standard library 
that isn’t all that Swifty due to the lack of statically-enforced safety as per 
usual in the rest of the library.

>   * If you have you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?

This is a tricky question in this context b/c pretty much every non-toy 
language with a non-toy standard library will have its own take on 
collections-and-iteration; it also makes it very hard to be concise, as th

Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-12 Thread plx via swift-evolution

> On Apr 12, 2016, at 6:11 PM, Haravikk  wrote:
> 
> I’m a +1 for the proposal (but as I’ve implemented a bunch of collections 
> recently I’m not sure I’m looking forward to having to update my code to 
> reflect the new pattern ;)
> 
> But I’m interested by these concerns:
> 
>> On 12 Apr 2016, at 17:57, plx via swift-evolution > <mailto:swift-evolution@swift.org>> wrote:
>> 
>> # 1: Relatively Unsafe, Pointer-Like Semantics
>> # 2: Index Invalidation Unrepresented In Type System 
> 
> It seems to me as though we could solve #1 by solving #2 actually; if we knew 
> when indices were invalid, then unless we’re storing .endIndex or using 
> .startIndex or .endIndex on an empty collection (rather than .first and 
> .last) then there should no issues of the safety of these “pointers" anymore.

FWIW I think “solving” invalidation in the sense of being able to detect 
invalidity is useful, but what I’d personally be more interested in is e.g. 
something like this:

  protocol Collection {

// throw this into the definition:
static var indexCharacteristics: IndexCharacteristics { get }

  }
  
  extension RangeReplaceableCollection {

mutating func removeElementsFailing(@noescape predicate: (Element) -> Bool) 
{
  if Self.indexCharacteristics.removalOnlyInvalidatesRightward() {
// presumptive “fast path”, deleting “back-to-front” to 
// avoid making a copy. Just for sake of illustration!
for index in self.indices.dropLast().reverse() where 
!predicate(self[index]) {
  self.removeAtIndex(index)
}
  } else {
// presumptive “slow path”, we rebuild ourself with the failing 
elements omitted
self = Self(self.lazy.filter() { predicate($0) })
// ^ assuming self-assignment allowed...
  }
}
  
  }

…e.g. some way to get some kind of coarse-grained behavior-characterization of 
“what actions invalidate which indices”, thereby allowing one to know when 
various approaches will work.

Invalidation is hard and I wouldn’t want anything held up to try and find a 
solution first.

> 
> The tricky thing is how to handle #2; we can do this at run-time by having 
> indices include a reference to their parent (or some kind of ID class), plus 
> a copy of a state variable which the collection will use to track 
> invalidating changes. If an index is passed to the collection with an 
> incorrect reference then it wasn’t for that collection, and if the states 
> don’t match then the index was invalidated. But really it’d be better if we 
> had some way to do this at compile-time which I think is what you meant; i.e- 
> some way for the compiler to track when an index was invalidated between 
> being stored and being used, so that passing it into the subscript or other 
> methods will produce a warning.
> 
> I suppose this could be done using attributes on the return values for index 
> generating properties/methods to assign some kind of tag which other methods 
> can then mark as having been invalidated, so that anything assigned that tag 
> can be considered invalid by the compiler if you try to use a value stored 
> before the invalidation. This is something that could be done afterwards I 
> think, so hopefully shouldn’t affect the proposal itself. There’ll be limits 
> to how far the compiler can track this though, but it could help to avoid 
> most of the simpler mistakes at least.
> 
> It’d be interesting if the compiler would also trace that an index belongs to 
> a collection, to prevent you accidentally using compatible ones with the 
> wrong collection when you have several; it’s good practice to check this with 
> preconditions, or assertions for performance, but the compiler doing it could 
> give more useful errors/advice.

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


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-12 Thread plx via swift-evolution

> On Apr 12, 2016, at 10:53 PM, Dmitri Gribenko  wrote:
> 
> On Tue, Apr 12, 2016 at 8:46 PM, plx via swift-evolution
>  wrote:
>> 
>> On Apr 12, 2016, at 6:11 PM, Haravikk  wrote:
>> 
>> I’m a +1 for the proposal (but as I’ve implemented a bunch of collections
>> recently I’m not sure I’m looking forward to having to update my code to
>> reflect the new pattern ;)
>> 
>> But I’m interested by these concerns:
>> 
>> On 12 Apr 2016, at 17:57, plx via swift-evolution
>>  wrote:
>> 
>> # 1: Relatively Unsafe, Pointer-Like Semantics
>> # 2: Index Invalidation Unrepresented In Type System
>> 
>> 
>> It seems to me as though we could solve #1 by solving #2 actually; if we
>> knew when indices were invalid, then unless we’re storing .endIndex or using
>> .startIndex or .endIndex on an empty collection (rather than .first and
>> .last) then there should no issues of the safety of these “pointers"
>> anymore.
>> 
>> 
>> FWIW I think “solving” invalidation in the sense of being able to detect
>> invalidity is useful, but what I’d personally be more interested in is e.g.
>> something like this:
>> 
>>  protocol Collection {
>> 
>>// throw this into the definition:
>>static var indexCharacteristics: IndexCharacteristics { get }
>> 
>>  }
>> 
>>  extension RangeReplaceableCollection {
>> 
>>mutating func removeElementsFailing(@noescape predicate: (Element) ->
>> Bool) {
>>  if Self.indexCharacteristics.removalOnlyInvalidatesRightward() {
>>// presumptive “fast path”, deleting “back-to-front” to
>>// avoid making a copy. Just for sake of illustration!
>>for index in self.indices.dropLast().reverse() where
>> !predicate(self[index]) {
>>  self.removeAtIndex(index)
>>}
>>  } else {
>>// presumptive “slow path”, we rebuild ourself with the failing
>> elements omitted
>>self = Self(self.lazy.filter() { predicate($0) })
>>// ^ assuming self-assignment allowed...
>>  }
>>}
>> 
>>  }
> 
> Hi plx,
> 
> In case of RangeReplaceableCollection, the index invalidation rules
> that we currently have in mind (but haven't documented in public
> documentation yet) imply that your fast path is always correct.

That’s good news!

Fact is, I only went with that because I was actually fishing around for the 
weakest generic collection protocol that supported removal, and that seems to 
be it.

It’d be a more compelling motivating example if it used, e.g.:

  // “fictional”, not in stdlib:
  protocol IndexDeletingCollection : Collection {

mutating func removeAtIndex(i: Index) -> Generator.Element

  }

…since there’d then be a more realistic chance of having multiple “flavors” of 
invalidation to consider.

But I could certainly live with a setup wherein generally protocols typically 
required “compatible” invalidation semantics on their indices.

> 
> Dmitri
> 
> -- 
> main(i,j){for(i=2;;i++){for(j=2;j (j){printf("%d\n",i);}}} /*Dmitri Gribenko */

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


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-13 Thread plx via swift-evolution

> On Apr 13, 2016, at 5:34 AM, Haravikk  wrote:
> 
> 
>> On 13 Apr 2016, at 04:46, plx via swift-evolution 
>>  wrote:
>> 
>> Invalidation is hard and I wouldn’t want anything held up to try and find a 
>> solution first.
> 
> Oh I agree, that was partly my point though; while this proposal may leave us 
> with the "un-Swifty" issue of being unable to explicitly handle invalidation, 
> it should be possible to solve that later, i.e- this proposal does’t make us 
> any more vulnerable to that problem than we are now, but I definitely agree 
> that we could do with some kind of invalidation mechanism in future that 
> developers can actually implement or respond to. I guess I was more thinking 
> out loud about whether the problem affects the proposal or not, but I don’t 
> think that solving it will place any restrictions on the API as proposed, 
> definitely deserves a proposal of its own once the new indexing system is in 
> place though!

There was a design document linked in one of the earlier discussions that IIRC 
suggested some collections would want to maintain a "revision count” value, 
with their indices then holding a snapshot of that “revision count” at their 
time of creation.

For something like Array that’s a bit heavyweight.

“Invalidation" is also IMHO a bit under-defined without an associated “for 
what?”:

  var letters = [“a”, “b”, “c”, “d”, “e”]

  // indexOfB == 1
  let indexOfB = letters.indexOf(“b”)

  letters.insert(“z”, atIndex: indexOfB)

…is `index` invalid or not? IMHO it would depend on what you want to do with it.


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


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-13 Thread plx via swift-evolution

> On Apr 12, 2016, at 5:25 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Apr 12 2016, plx  > wrote:
> 
>> Aside: `indices` being irregular can be a benefit in the context of
>> auto-complete.
>> 
>>* What is your evaluation of the proposal?
>> 
>> +1, very much.
>> 
>> As a change from the current model, it’s an across-the-board improvement for 
>> me,
>> at least.
>> 
>> In a bigger-picture sense I think Swift would be better off by going 
>> *further*
>> on certain aspects, but have said all that before.
>> 
>>* Is the problem being addressed significant enough to warrant a change to
>>Swift?
>> 
>> It is, again very much so.
>> 
>>* Does this proposal fit well with the feel and direction of Swift?
>> 
>> Depends on the framing of the question.
>> 
>> Compared to the previous model, it’s an unqualified YES.
>> 
>> As a general proposition, I think this design is a local optimum for overall
>> Swift-ness, but even so it’s creating a little un-Swifty pocket. It’s
>> “un-Swifty” in at least two ways:
>> 
>> # 1: Relatively Unsafe, Pointer-Like Semantics
>> 
>> Indices—unsurprisingly!—behave quite a bit like pointers, and similarly 
>> expose
>> *numerous* crashing combinations of `(value,operation)`:
>> 
>> - self[endIndex]
>> - self[startIndex] // <- when empty
>> - successor(of: endIndex)
>> - predecessor(of: startIndex)
>> 
>> …etc., which is *very much* reminiscent of the hazards of pointers. 
>> (Technically
>> “undefined” not “crashing”, but being realistic “crashing" is usually 
>> accurate).
> 
> No, these are unspecified in the general case, not undefined.  Unless
> you're working with, e.g. `UnsafeMutableBufferPointer` (or you have a
> data race), there's no undefined behavior.  The big problem with
> pointers isn't what happens when they crash; it's what happens when they
> *don't*.
> 
>> Although Swift uses `Optional` to mitigate the hazards of `nil` pointers 
>> (etc.),
>> you’re still left to your own devices for handling indices.
> 
> `Optional` is not “mitigating hazards;” it's encoding the possibility of
> null in the type system.  It's non-optional things that mitigate hazards.
> 
>> This isn’t news to anyone here, I’m sure, and may even be unavoidable; I’m 
>> just
>> pointing it out as an uncharacteristically-unsafe area in Swift’s standard 
>> APIs,
>> and closer to how `!` and IOUs behave than otherwise typical.
> 
> Any time there's a required relationship between two things, e.g. a
> receiver and an argument, you have a precondition.  The existence of a
> precondition does not make something unsafe at all in the sense that
> Swift uses the term.  Safety in swift is about type and memory safety in
> the absence of data races, not about having APIs that respond sensibly
> to every possible combination of arguments.  Int.max + 1 will trap, but
> that doesn't make addition unsafe.
> 
> Saying that it's close to how `!` behaves is not at all far from the
> truth, because `!` has a precondition that its argument is non-nil.

I meant it as a much more exact analogy.

In a collections-move-indices world, you *could* handle indices as pointers 
have been handled, bringing in support from the type-system:

  enum SaferIndex {
case Position(T)
case End
  }

…(yes, this is more-or-less `Optional` by another name).

The assumption above is `T` would be today’s “Index” types, w/o the value used 
for `endIndex` (e.g. 0..> To help illustrate the claim, here’s a strawman “safe” API—for illustration
>> only, not advocacy!—that would be safer and thus perhaps more “Swift-y”:
> 
> I think there's a prevalent misunderstanding (IOW, I don't mean to
> single out this post or this poster) about what “safe” means in Swift
> and what the features of a Swifty API are and should be.  This
> is a big topic worthy of much more time than I can devote here, but
> here's a thought to start with:
> 
> A Swifty API helps you reason effectively about the correctness of your
> code, and in part that means we provide enough preconditions on
> arguments to avoid complicating result types, and code to handle
> results, with optional-ness.
> -- 
> Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-13 Thread plx via swift-evolution

> On Apr 13, 2016, at 4:26 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue Apr 12 2016, Brent Royal-Gordon  wrote:
> 
>> In these cases, it would be better if the `successor(of:)` method was
>> designed in a way that acknowledged and encapsulated the bounds check
>> that is usually required when it is used:
>> 
>>  while let nextIndex = collection.successor(of: index) {
>>  …
>>  index = nextIndex
>>  }
> 
> I disagree; it doesn't make sense that I should have to check for nil
> when I'm not really interested in the end of the collection as in my
> example above.  Many other nontrivial algorithms will have the same
> characteristic.  If all you need is to loop through indices to the end,
> there are lots of ways to do it.  
> 
> Looking closer, what you've got here is actually a *highly* unusual
> case, where you want a pair of indices that you want to always point to
> successive elements.  I do not know of any algorithm that would use this
> except maybe bubblesort, and frankly I cannot see any reason to change
> the standard library to support it.  Am I missing something?

Enumerating adjacent pairs from a sequence has its uses; when it’s a collection 
you can make the "adjacent pairs” thing itself a collection, and a pair of 
adjacent indices from the source collection makes a natural choice for the 
non-end-index indices.

In this case I agree the language doesn’t need to change; just write the 
generic “adjacent pairs” thingy and then use it like so:

  // if you *really* wanted values:
  for (left,right) in collection.adjacentPairs() { …

  // if you *did* actually want indices;
  for (leftIndex,rightIndex) in collection.indices.adjacentPairs() {

…but all the uses I make of it for higher-level things than e.g. “algorithms” 
in the STL sense.

> 
>> Given the difficulties of statically detecting index invalidation, I
>> totally agree that (as you discussed in a section I've snipped) we
>> can't statically prove indexes are safe. But we can, at the point
>> where we generate an index, easily check if that index is *currently*
>> valid. And it's something that most callers will have to do anyway if
>> we don't do it ourselves.
> 
> I really disagree with the assertion that most callers will need to do
> this.  It certainly isn't a normal thing to do in any algorithm I know
> of.  If you think I'm wrong (not unheard of!), I suggest you code up the
> method you've requested and try to apply it in actual code that
> manipulates indices, and show us how it improved the code.
> 
>>> We will change the index(_:stepsFrom:limitedBy:) overload to return
>>> an optional, and we will see what other implications it has, and how
>>> it fits into the rest of the system.
>> 
>> I'm glad to hear you'll evaluate this option, and I think it can give
>> us both what we want from this API.
>> 
>> I think having the most high-level operations incorporate bounds
>> checks, while the lower-level ones don't, is a good compromise. 
> 
> That may be the pattern you discern in Swift's bounds checks, but I just
> want to be very clear that it's not a criterion we use to make the
> determination.  I would love it if we had a more systematic way to make
> the choice to insert bounds checks or not, but for now it remains
> something of an art, trying to balance usability and performance
> concerns.
> 
>> If we encourage people to use `index(_:stepsFrom:limitedBy:)` unless
>> they know what they're doing, naïve clients will get an implicit
>> bounds check, while sophisticated, speed-sensitive clients can use
>> methods like `successor(of:)` which require them to check bounds
>> manually.
> 
> It's not a bounds check.  There are lots of ways to pass a limit that's
> outside the bounds of the collection, and you can pass a limit that's in
> the opposite direction from the offset.  If they happen to pass the
> collection's endIndex and a positive offset, it degenerates to a bounds
> check, but that's not what this method is for.
> 
> I will encourage people to use high-level algorithms where possible, so
> they're not doing index manipulations directly.  Anyone doing low-level
> index manipulations is probably implementing an algorithm, and I'll
> encourage them to do whatever will be most efficient, and then test the
> algorithm on some very strict models of Collection, that check
> everything.  You can find some of these in the StdlibUnittest library in
> the swift source tree.
> 
>> (There might even be a case for offering bounds-checked
>> `successor(of:limitedBy:)` and `predecessor(of:limitedBy:)` methods to
>> give people bounds-checked alternatives to all three.)
>> 
>>> Thanks again, Brent.
>> 
>> Thank you!
> 
> -- 
> Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolu

Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-13 Thread plx via swift-evolution

> On Apr 13, 2016, at 5:36 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 13 2016, plx  wrote:
> 
>>On Apr 12, 2016, at 5:25 PM, Dave Abrahams via swift-evolution
>> wrote:
>> 
>>on Tue Apr 12 2016, plx
>> wrote:
>> 
>>Aside: `indices` being irregular can be a benefit in the context of
>>auto-complete.
>> 
>>* What is your evaluation of the proposal?
>> 
>>+1, very much.
>> 
>>As a change from the current model, it’s an across-the-board 
>> improvement
>>for me,
>>at least.
>> 
>>In a bigger-picture sense I think Swift would be better off by going
>>*further*
>>on certain aspects, but have said all that before.
>> 
>>* Is the problem being addressed significant enough to warrant a 
>> change
>>to
>>Swift?
>> 
>>It is, again very much so.
>> 
>>* Does this proposal fit well with the feel and direction of Swift?
>> 
>>Depends on the framing of the question.
>> 
>>Compared to the previous model, it’s an unqualified YES.
>> 
>>As a general proposition, I think this design is a local optimum for
>>overall
>>Swift-ness, but even so it’s creating a little un-Swifty pocket. It’s
>>“un-Swifty” in at least two ways:
>> 
>># 1: Relatively Unsafe, Pointer-Like Semantics
>> 
>>Indices—unsurprisingly!—behave quite a bit like pointers, and 
>> similarly
>>expose
>>*numerous* crashing combinations of `(value,operation)`:
>> 
>>- self[endIndex]
>>- self[startIndex] // <- when empty
>>- successor(of: endIndex)
>>- predecessor(of: startIndex)
>> 
>>…etc., which is *very much* reminiscent of the hazards of pointers.
>>(Technically
>>“undefined” not “crashing”, but being realistic “crashing" is usually
>>accurate).
>> 
>>No, these are unspecified in the general case, not undefined. Unless
>>you're working with, e.g. `UnsafeMutableBufferPointer` (or you have a
>>data race), there's no undefined behavior. The big problem with
>>pointers isn't what happens when they crash; it's what happens when they
>>*don't*.
>> 
>>Although Swift uses `Optional` to mitigate the hazards of `nil` 
>> pointers
>>(etc.),
>>you’re still left to your own devices for handling indices.
>> 
>>`Optional` is not “mitigating hazards;” it's encoding the possibility of
>>null in the type system. It's non-optional things that mitigate hazards.
>> 
>>This isn’t news to anyone here, I’m sure, and may even be unavoidable;
>>I’m just
>>pointing it out as an uncharacteristically-unsafe area in Swift’s
>>standard APIs,
>>and closer to how `!` and IOUs behave than otherwise typical.
>> 
>>Any time there's a required relationship between two things, e.g. a
>>receiver and an argument, you have a precondition. The existence of a
>>precondition does not make something unsafe at all in the sense that
>>Swift uses the term. Safety in swift is about type and memory safety in
>>the absence of data races, not about having APIs that respond sensibly
>>to every possible combination of arguments. Int.max + 1 will trap, but
>>that doesn't make addition unsafe.
>> 
>>Saying that it's close to how `!` behaves is not at all far from the
>>truth, because `!` has a precondition that its argument is non-nil.
>> 
>> I meant it as a much more exact analogy.
>> 
>> In a collections-move-indices world, you *could* handle indices as pointers 
>> have
>> been handled, bringing in support from the type-system:
>> 
>> enum SaferIndex {
>> case Position(T)
>> case End
>> }
>> 
>> …(yes, this is more-or-less `Optional` by another name).
>> 
>> The assumption above is `T` would be today’s “Index” types, w/o the value 
>> used
>> for `endIndex` (e.g. 0..> of
>> `DictionaryIndex` and `SetIndex`, and so on).
> 
> No, you can't, at least not usefully.  An Index that's at the end of one
> collection is in the middle of another, or with a suitably-modified version
> of the same collection.  

Sure, in certain concrete scenarios it’s possible for one collection’s indices 
to have such relationships to some other collection.

But, what of it? 

In a generic context you can’t assume this; in a concrete context you naturally 
have more information.

Slices would become problematic, I’ll grant.

>  var x = [1, 2]
>  let i = x.index(1, stepsFrom: x.startIndex)
>  x.removeLast()
>  x[i]   // fatal error: Index out of range

Indices can become invalid; this imposes preconditions. I don’t get it.

> 
> The converse is also true: subscripting on a collection's endIndex is
> sometimes just fine, even with no mutation in sight.
> 
>  let a = (0..<10).reversed()
>  print(Array(a))  // “[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]”
> 
>  let b = a.prefix(9)
>  print(Array(b))  // “[9, 8, 7, 

Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-13 Thread plx via swift-evolution

> On Apr 13, 2016, at 5:36 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Wed Apr 13 2016, plx  > wrote:
> 
> Seriously, just because Swift has Optionals and they're useful for
> safety in some scenarios (compared with allowing everything to be
> nullable) does not mean that it's going to be “Swiftier” to apply a
> similar pattern everywhere.

This reminds me of something I was going to ask about earlier and forgot. 

Coming from other languages, I’ve definitely brought with me an assumption that 
“make invalid states unrepresentable (except where unavoidable)” is the right 
way to go, with deviations from that rule requiring scrutiny.

Is that outlook actually something the core team considers “Swift-y” or not, 
though? 

The connection to the point you’re making here and the question is that 
adopting this design style *will* lead to lots of optionals in lots of places.

> 
>> use an enum to reintroduce that value when necessary—than to `!`.
>> 
>> I don’t think the above is an *improvement* over the proposal, but it’s a 
>> route
>> that could have been taken.
> 
> I believe it would be hard to make such a design work at all, and if you
> could make it work I think you'd end up with exactly the problem this
> proposal aims to solve: references inside indices.  So, I don't think
> it's even a possibility, really.
> 
>> 
>> 
>>To help illustrate the claim, here’s a strawman “safe” API—for
>>illustration
>>only, not advocacy!—that would be safer and thus perhaps more 
>> “Swift-y”:
>> 
>>I think there's a prevalent misunderstanding (IOW, I don't mean to
>>single out this post or this poster) about what “safe” means in Swift
>>and what the features of a Swifty API are and should be. This
>>is a big topic worthy of much more time than I can devote here, but
>>here's a thought to start with:
>> 
>>A Swifty API helps you reason effectively about the correctness of your
>>code, and in part that means we provide enough preconditions on
>>arguments to avoid complicating result types, and code to handle
>>results, with optional-ness.
>> 
>>-- 
>>Dave
>> 
>>___
>>swift-evolution mailing list
>>swift-evolution@swift.org
>>https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> 
> 
> -- 
> Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0065 A New Model for Collections and Indices

2016-04-14 Thread plx via swift-evolution

> On Apr 14, 2016, at 12:12 PM, Dave Abrahams via swift-evolution 
>  wrote:
>>> 
>>> No, you can't, at least not usefully.  An Index that's at the end of one
>>> collection is in the middle of another, or with a suitably-modified version
>>> of the same collection.  
>> 
>> Sure, in certain concrete scenarios it’s possible for one collection’s
>> indices to have such relationships to some other collection.
>> 
>> But, what of it? 
>> 
>> In a generic context you can’t assume this; 
> 
> That's incorrect.  A slice's indices are *documented* as having a
> particular relationship to those of the thing it was sliced from.  This
> applies everywhere.  A dictionary's keys and values use the same indices
> as the dictionary itself, and have a correspondence.

You’re right, of course; I rarely use slices and completely overlooked them.

I also phrased it badly, b/c what I was trying to express is that code like the 
below is (I think?) unlikely to work generically:

  extension Collection where Element:Equatable {

 // plz don’t do this
 func hasValueMismatch(with other: Self, at index: Index) -> Bool {
   return self[index] != other[index]
 }

 // plz don’t do this either
func hasValueMismatch(with other: K, at index: Index) -> Bool { 
  return self[index] != other[index]
}

  }

…(you would’t write the above anyway, but it illustrates the kind of "generic 
context" I had in mind when I wrote it).

> 
>> in a concrete context you naturally have more information.
>> 
>> Slices would become problematic, I’ll grant.
>> 
>>> var x = [1, 2]
>>> let i = x.index(1, stepsFrom: x.startIndex)
>>> x.removeLast()
>>> x[i]   // fatal error: Index out of range
>> 
>> Indices can become invalid; this imposes preconditions. I don’t get
>> it.
> 
> My point is that whether i is at the end or not cannot be encoded in i.

I see the miscommunication, now. Of course you can’t encode that.

I’ve put a couple examples down below as a last effort at communicating what 
I’m getting at it. 

>>> The converse is also true: subscripting on a collection's endIndex is
>>> sometimes just fine, even with no mutation in sight.
>>> 
>>> let a = (0..<10).reversed()
>>> print(Array(a))  // “[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]”
>>> 
>>> let b = a.prefix(9)
>>> print(Array(b))  // “[9, 8, 7, 6, 5, 4, 3, 2, 1]”
>>> 
>>> print(a[b.endIndex]) // “0” (correct, supported behavior)
>> 
>> I believe we are back to “subscripting one collection with *another*
>> collection's `endIndex`, no?
> 
> Totally legit, as mentioned above.  a.prefix(9) returns a slice of a.
> 
>> Are there any circumstances where a collection *can* be
>> usefully-subscripted with its *own* `endIndex`?
> 
> var a = [1]
> let i = a.endIndex
> a.append(2)
> print(a[i]) // “2”
> 
>>> 
>>> Of course,
>>> 
>>> b[b.endIndex]// As a matter of QOI: fatal error: out of bounds: 
>>> index >= endIndex
>>> 
 
 It would’ve been awkward to do this under the previous status quo—e.g. 
 even for
 arrays your indices would have to have a back-reference to get the count, 
 and
 thus couldn’t be plain integers—but the collection will now always be 
 present to
 provide such info.
 
 Cons:
 
 - more overhead than “bare” indices
 - doesn’t address invalidation (but what does, really?)
 
 Pros:
 
 - easier in some ways to handle things like e.g 0…Int.max
 - the endIndex equivalent *never* invalidates 
 - compile-time help for end-index checking
 
 Overall this *would* bring the treatment of indices closer to that for 
 `?`—e.g.,
 redefine the core type to omit the `nil`-like value, 
>>> 
>>> Sorry, but that's the opposite of what `?` is doing: it *adds* a nil
>>> value.  
>> 
>> …I must have been unclear.
>> 
>> Step 1: Define T* = { "all memory addresses” (nil included) }
>> Step 2: Define T = T* \ { nil } (e.g. "non-null pointers")
>> 
>> …is what I was trying to summarize via “redefine the core type to omit
>> the `nil`-like value” (which is the important part here).
> 
> Sorry, that's still unclear to me.  I just don't see what you're getting
> at.
> 
>> Anyways, having `endIndex` directly inhabit the same type as the
>> “good” indices has some pros and some cons; it’s not an IMHO one-sided
>> situation as with `nil`.
> 
> Maybe, but my point is that many things in the current model are
> incompatible with the other arrangement.  If you wanted to change the
> arrangement, you'd need to re-think the current model from the ground
> up, including index invalidation, how algorithms interact, the
> relationship of slices to the thing they're sliced from, etc...
> 
> So what you're suggesting is an interesting hypothesis, but to me it's
> not by any means obviously workable.

You’re completely right about slices. I’ll provide a couple concrete examples 
before addressing the rest.

Here are three collection-combinators (or adapters I think you’d call them):

  // Colle

Re: [swift-evolution] [Proposal draft] Enhanced floating-point protocols

2016-04-15 Thread plx via swift-evolution
+1; this is great!

I have nothing but good things to say about the proposal itself.

I have two smaller questions, however; I apologize if they are off-topic.

One is if there’s any ETA or similar for a glimpse at the “complete picture” of 
Swift’s revised numeric protocols; these floating-point protocols look really, 
really good, but this is also (I think) the first glimpse at the new 
`Arithmetic` protocol, and there’s also a new “Integer” protocol coming…and 
it’d be nice to get a sense of the complete vision here.

My other question is potentially subsumed by the above, but I want to raise it 
now: it’d be great if there was some standardized protocol/vocabulary to use 
when converting between various numeric representations that was:

- easy for custom numeric types to *adopt* correctly (e.g. if one were to write 
a fixed-point type, or a rational type, etc.)
- easy for non-experts to *use* correctly for non-expert purposes

…since such conversions from one representation to another are at least IMHO a 
dangerous area; if you know what you’re doing it’s not dangerous, but e.g. even 
if someone is only trying to go from Double -> Int:

- they probably aren’t an expert, doing expert numerical things
- they may not have a solid understanding of floating point (NaN, infinities, 
etc.)
- they thus may not know they may *need* to be careful here
- they may not know *how* to be careful, even if they know they *should* be
- they may not be able to be careful *correctly*, even if they attempt it

…and so it’d again be great if the revised numeric protocols allow as broad a 
range of such conversions as possible to be handled by generic code in the 
standard library. 

It certainly looks like `FloatingPoint` protocol itself provides enough 
information to allow an expert to write generic version of most floating point 
-> integer conversion variants I can think of, but I’m not an expert…but it’d 
be great if e.g. there was some simpler protocol other custom numeric types 
could adopt to take advantage of expert-written generic conversions to other 
numeric types. 

I can provide examples if this is unclear, and if it’s off-topic it can wait 
for another time. 

This `FloatingPoint` revision itself looks really really good! 

> On Apr 14, 2016, at 6:55 PM, Stephen Canon via swift-evolution 
>  wrote:
> 
> Enhanced floating-point protocols
> 


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


Re: [swift-evolution] ValueEnumerable protocol with derived implementation for enums

2016-04-16 Thread plx via swift-evolution

> On Apr 15, 2016, at 9:00 PM, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> This discussion is about a proposal for API to enumerate/count all possible 
> values of a type, particularly enums. The goal is to address potential issues 
> with an old proposal, so it can go up for review soon.
> 
> Core Team / Standard Library Team feedback would be particularly welcome 
> here, because we want this feature to mesh well with the goals & future 
> directions that are already in mind for Swift. If any details the core team 
> would like to see are missing from the proposal, please let us know now.
> 
> Background reading:
> 
> • 2015-12-08: "List of all Enum values (for simple enums)" — 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/10064 
> 
> • 2015-12-21: "Proposal: Enum 'count' functionality" 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/644 
> 
> • 2016-01-17: "Draft Proposal: count property for enum types" 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/3678 
> 
> • 2016-01-18: "Pre-proposal: CaseEnumerable protocol (derived collection 
> of enum cases)" at 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/3701 
> 
> • 2016-01-20: My subsequent proposal PR #114: 
> https://github.com/apple/swift-evolution/pull/114 
> 
> 
> A lot has happened since then:
> 
> • 2016-03-03: "[Manifesto] Completing Generics" 
> http://thread.gmane.org/gmane.comp.lang.swift.evolution/8484 
> 
> • 2016-03-03: "[Accepted with modifications] SE-0023 API Design 
> Guidelines" http://thread.gmane.org/gmane.comp.lang.swift.evolution/8585 
>  & 
> http://apple.github.io/swift-internals/api-design-guidelines/ 
> 
> • 2016-03-09: Brent's proposal PR #199: 
> https://github.com/apple/swift-evolution/pull/199 
> 
> 
> Brent brought up some great points in his proposal, but ultimately closed the 
> PR in anticipation of further discussion. I'm sorry I haven't had much time 
> to put into this until now, but I'd like us to get the discussion going again.
> 
> I believe the community is in agreement about the following:
> 
> • The "allValues" behavior should be provided by conformance to some 
> protocol, named ValueEnumerable or ValuesEnumerable or similar.
> • The compiler should derive an allValues implementation for "simple" 
> enums (those without associated values).
> 
> There are a couple things which we must still decide:
> 
> ### Should the ValueEnumerable protocol expose the allValues property, or 
> should it be an empty protocol like ErrorType (ErrorProtocol)? If exposed, 
> what is its type?

# General Remarks

My 2c is that if this is to go in the standard library, it should be done 
“right”, which would be more like this version of it:

protocol ValueEnumerable {
  associatedtype ValueCollection : Collection where 
ValueCollection.Iterator.Element == Self
  static var allValues: ValueCollection
}

…and that this concept should simply *wait* for that feature to be available 
before going into the standard library. 

The reason I say this is simply b/c it sounds like this proposal wants to be 
able to support more than simple enumerations, in which case having some 
flexibility in the representation seems appropriate. Consider e.g.:

  struct AxisPolicy3D> {
var x: Policy
var y: Policy
var z: Policy
  }

  extension AxisPolicy3D : ValueEnumerable {

static let allValues: ValueCollection = 
product(Policy.allValues,Policy.allValues,Policy.allValues).lazy.map() { 
(x,y,z) 
in
AxisPolicy3D(x: x, y: y, z: z)
}

  }

…and similar, wherein the cost of *requiring* an array here could become rather 
large.

But I have a couple general concerns here:

# Resiliency 

My understanding is that the design for resiliency vis-a-vis enumerations is 
meant to allow enumerations to have cases added in future revisions (and 
perhaps also private cases? I didn’t follow resiliency closely). 

If that’s right, and this protocol is supposed to go into the standard library, 
it might also need to address such issues. I have no help to offer and would 
love to be wrong about this point.

# Scope (or: Beyond Simple Enumerations?)

On the one hand, I don’t see any reason *not* to design the protocol so that it 
*could* be adopted by types other than simple enumerations. 

On the other hand, I think the value of having this in place for 
simple-enumerations is huge, and I’m more than a bit 

Re: [swift-evolution] [Draft] Expanded min/max algorithms

2016-04-17 Thread plx via swift-evolution
I like the idea. It worries me a bit if the general recipe for such situations 
is to add dedicated-purpose methods like `_customIndexOfMinComparableElement` 
(etc.) to standard-library protocols; it *will* work, but is only going to work 
for the methods that get such treatment.

If it were feasible, I’d *greatly* prefer having some more-general way to 
(conditionally?) add overridable methods to a protocol, e.g.:

  // made-up declaration, all declared methods below are now overridable
  // on suitable types
  overridable extension Collection where Iterator.Element: Comparable {

func min() -> Iterator.Element?

  }

…but am not sure that’s even realistically possible.

The reason I bring it up is that I’d hope that `indexOf`, `contains`, and also 
`upperBound`/`lowerBound` would merit a similar treatment to that proposed here 
for min, max, and minmax (if not already given such; if they get added to 
standard-library; etc.).

Moving on, wrt these min/max elements themselves: I think any expectation about 
*which* index gets returned should be document—either no such expectation in 
general, or a specific expectation, or that each concrete collection should 
document the expectation, etc.—because for the minIndex/maxIndex methods 
different approaches can yield different results.

EG: consider an order-maintaining collection that has contents ~ 
`[1,1,1,2,2,2,3,3,3]`. There are multiple candidates for both `minIndex` and 
`maxIndex`.

I don’t have a strong opinion on what the right preference would be here, but I 
think whatever the behavior winds up being should be at least documented.

Finally, FWIW if more of these semi-hidden methods become something exposed to 
users (as “advanced” options, perhaps, but still) I think replacing `??` with 
something like

  enum AdvancedCustomizationPointResult {
case NotCustomized // like `nil` for ??
case NoResult // like `Optional(nil)` for ??
case Result(T) // like `Optional(T)` for ??
  }

…might be worth considering (except with a better name than that). I’m not 
trying to backdoor optional protocol methods or anything, it just seems 
advisable to more-explicitly represent the intent (?? certainly works but feels 
a bit obscure).

> On Apr 17, 2016, at 1:44 AM, Nate Cook via swift-evolution 
>  wrote:
> 
> Hello all,
> 
> Attached is a draft of a proposal to expand the min and max sequence APIs to 
> better handle collections and to support future sorted sequences/collections. 
> The proposal is in a gist here 
>  and 
> inlined below—would love to hear any comments or feedback before submitting 
> the proposal.
> 
> Nate
> 
> 
> Proposal: Expanded min/max algorithms
> This proposal would expand on the min() and max() sequence methods to add 
> methods that return the corresponding index for a collection, efficiently 
> find the minimum and maximum elements or indices at the same time, and 
> provide extension points for sorted collections to provide all these results 
> more efficiently.
> 
> Related Bugs: SR-889  and SR-890 
> 
> Motivation
> The Sequence protocol currently offers min() and max() methods that return 
> the minimum and maximum elements of a sequence or collection. Unfortunately, 
> there are applications where these methods do not provide enough flexibility 
> to be useful.
> 
> First, if the user of a collection wants not just to get the minimum value 
> but also to operate on it in some way (e.g., mutation or just accessing it 
> multiple times), she would need the index of the minimum element. The current 
> APIs don't support that, so she would need to write her own.
> 
> Second, the writer of a sorted collection is currently unable to provide 
> efficient responses to the min() and max() methods when used in a generic 
> context, even though these should be O(1) operations. Just like Set can 
> respond quickly to contains(_:) even in a generic context, so too should new 
> sorted collections be able to optimize their responses.
> 
> Finally, getting the minimum and maximum elements (or indices) of a 
> collection or sequence currently requires calling both min() and max(). With 
> two calls, every element is iterated and compared twice. When you need both 
> results, finding both the minimum and the maximum at the same time is more 
> efficient, requiring only a single pass and 25% fewer comparisons.
> 
> Proposed solution
> This proposal has three parts:
> 
> Adding minIndex() and maxIndex() methods to Collection that return the index 
> of the minimum and maximum elements, respectively.
> 
> let numbers = [30, 40, 10, 20, 60, 50]
> 
> if let i = numbers.minIndex() {
> print("\(i): \(numbers[i])")   // 2: 10
> }
> Adding minmax() and minmaxIndices() methods to Sequence and Collection, 
> respectively, to calculate the values (or indices) of the minimum a

Re: [swift-evolution] [Draft] Expanded min/max algorithms

2016-04-17 Thread plx via swift-evolution
I *quite* like `extrema`/`indicesOfExtrema` over minmax.

> On Apr 17, 2016, at 10:03 AM, Patrick Pijnappel  
> wrote:
> 
> I like the idea. A few notes on naming:
> – minIndex is somewhat confusing to me (it sounds like it's getting the 
> minimum index, i.e. indices.minElement()). How about indexOfMin() or 
> indexOfMinElement()?
> – minmax() also doesn't read very well to me, plus it should technically be 
> minMax() which is kinda ugly. Perhaps limits() or extrema()? The latter would 
> be the most correct mathematically. For the index form that would give e.g. 
> indicesOfExtrema().

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


Re: [swift-evolution] [Idea] Replace enumerate() with something more explicit

2016-04-17 Thread plx via swift-evolution
If something is to happen I cast my vote for #2.

I actually—and intentionally—use what that would call `numbered()` rather 
frequently; it’s not hard to write but not having to write it is nicer.

Since the “indexed” version is also useful it’d be nice to have both, and with 
unambiguous names.

> On Apr 15, 2016, at 4:59 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> A discussion in the "mapValues" thread reminded me of a longstanding issue I 
> have with Swift.
> 
> `enumerate()` is an attractive nuisance. (That is, it looks like the thing 
> you want, but it's not actually the right one.) Most people use it because 
> they want to enumerate over indices and elements at the same time. In 
> reality, though, the first element of an `enumerate()` tuple is not the 
> index—it's a monotonically increasing integer starting at 0. That *happens* 
> to work for `Array`:
> 
>>1> let array = Array(0..<10) 
>>2. for (i, elem) in array.enumerate() { 
>>3. print(array[i]) 
>>4. }
>>  0
>>  1
>>  2
>>  3
>>  4
>>  5
>>  6
>>  7
>>  8
>>  9
> 
> But if you stray even a little bit from the golden path, things start to go 
> wrong:
> 
>>5> let range = array[2..<8]
>>6. for (i, elem) in range.enumerate() { 
>>7. print(range[i])
>>8. } 
>>  fatal error: Index out of bounds
> 
> You can scarcely blame users for making this mistake, though—"The Swift 
> Programming Language" encourages the misconception. "Iterating Over an Array" 
> in "Collection Types":
> 
>> If you need the integer index of each item as well as its value, use the 
>> `enumerate()` method to iterate over the array instead. For each item in the 
>> array, the `enumerate()` method returns a tuple composed of the index and 
>> the value for that item.
> 
> 
> While the text is technically accurate—it only talks about iterating over 
> arrays and the numbers generated by `enumerate()` happen to correspond to 
> array indices—it creates a false implication that `enumerate()` is defined to 
> return indices, which isn't true of other collections.
> 
> This is made worse by the fact that `enumerate()` is not really a good name. 
> It is not a common word, so people don't read it and immediately understand 
> what it does; they memorize a Swift-specific meaning, and that meaning may 
> incorporate the misconception that `enumerate()` includes indices. It is also 
> not technically accurate: although it has "number" in its Latin roots, 
> "enumerate" means either "to count" or "to list", not "to number" (i.e. 
> assign numbers to). I know `enumerate()` is used in a couple of other 
> languages (certainly Python, possibly others), but I don't think that 
> overrides the fact that it's confusing.
> 
> I have three possible solutions to propose.
> 
> 
> 
> OPTION ONE
> 
> * Remove `enumerate()`.
> 
> * Provide a type and postfix operator which allows you to write an infinite 
> sequence as `0...`. (This might call a ClosedRange constructor which 
> constrains the type to a protocol which provides `max`. This would imply that 
> `FloatingPoint` and `Integer` protocols would need to conform to a common 
> protocol declaring a `max` property, and in the case of `FloatingPoint`, 
> `max` should probably be positive infinity.)
> 
> * Fix-It calls to `x.enumerate()` as `zip(0..., x)`. This is more complicated 
> to look at, but it's *far* more explicit about what the operation actually 
> does. (For bonus points, we could perhaps look at how the EnumerateSequence 
> is used, and if the number is used as an index, go with `zip(x.indices, x)` 
> instead.)
> 
> 
> 
> OPTION TWO
> 
> * Rename `enumerate()` to something more explicit, like `withIntegers()` or 
> `numbered()`. (It might even make sense to add a `from:` parameter which 
> defaults to 0.)
> 
> * Add to Collection an equivalent method with a similar name that provides 
> indices, like `withIndices()` or `indexed()`.
> 
> * Fix-It calls to `enumerate()` into either `numbered()` or `indexed()` (or 
> whatever they end up being called) depending on the way they are used.
> 
> 
> 
> OPTION THREE
> 
> Combine the other two options:
> 
> * Provide the infinite numeric sequence type from Option One.
> 
> * Provide `numbered()` and `indexed()` (or whatever) methods which are 
> explicitly typed to merely zip over the sequence/collection with an infinite 
> integer sequence/Indices collection.
> 
> -- 
> 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] [Review] SE-0065 A New Model for Collections and Indices

2016-04-18 Thread plx via swift-evolution

> On Apr 18, 2016, at 4:52 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
>> 

> 
> Again you're encoding “I'm at the end” in the index, which as we've
> agreed does not work.

If nothing else, it works—and seems natural—for linked lists. 

Sorry; if I’d remembered this elementary example sooner I would’ve lead with it.

I’ll point it out then be completely done.

> So one special index value “moves automatically as the collection changes” and
> all others do not.  Doesn't seem like an advantage to me.  It's easy to
> imagine having subtle bugs due to this difference. 

Again, if you implement a textbook linked-list under collections-move-indices, 
the natural representation for the indices is arguably `ListNode?` (or 
whatever), wherein you use `nil` for the end index. 

As a consequence, at least in this scenario you wind up with the 
semantics/behavior sketched previously for `endIndex`. 

No further reply is needed; thank you for sharing your insight.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0067: Enhanced Floating Point Protocols

2016-04-20 Thread plx via swift-evolution
FWIW, you can avoid the multiple-preposition issue it differently:

- isLessThanOrEqual(to:) => isNotGreaterThan(_:), isAtOrBelow(_:), etc.

…neither of which I can claim to really like, but such possibilities exist.

Offering in case there's a better phrasing along similar lines.

> On Apr 20, 2016, at 3:08 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I'm saying something else. The preposition that goes with "less" is "than," 
> while "to" goes only with "equal." By making "to" a parameter label you've 
> got {less than or equal} to, which is inelegant because the label cannot be 
> distributed to both parts--i.e. one cannot say "less than to or equal to."
> 
> Put another way, I could just as well rewrite the method as 
> `equalToOrLess(than:)`. Now, the parameter is labeled "than" instead of "to," 
> yet the parameter serves the same purpose. Thus, I argue that the proposed 
> method name may meet the letter of the Swift guidelines but is awkward.
> 
> On Wed, Apr 20, 2016 at 14:44 Dave Abrahams via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> on Tue Apr 19 2016, Xiaodi Wu  > wrote:
> 
> >  * What is your evaluation of the proposal?
> >
> > +1 in intent. Specifics require further refinement. For example:
> >
> > Internal inconsistencies in capitalization:
> > * `signalingNaN` but `isSignalingNan` and `isNan`
> >
> > Parameter labels, or whatever they're called now, do not reflect newly
> > adopted Swift syntax in SE-0046:
> > * `static func maximum(x: Self, _ y: Self) -> Self` should be `static
> > func maximum(_ x: Self, _ y: Self) -> Self`, etc.
> >
> > Infelicitous use of prepositions to conform superficially to new
> > naming guidelines:
> > * `isEqual(to:)` is fine, but for consistency there's
> > `isLessThanOrEqual(to:)`, which is not fine, because the preposition
> > "to" applies only to "equal" and not to "less than"
> 
> That seems like a huge stretch to me.  Are you claiming it's wrong to
> say “x is less than or equal to y,” or are you saying something else?
> 
> --
> Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Mutability for Foundation types in Swift

2016-04-22 Thread plx via swift-evolution
On the one hand I like the idea (and particularly like the foundation types 
having meaningful `mutating` annotations, loosely speaking).

On the other hand I have two questions:

1. will the NS types actually remain visible/usable (on supported platforms, 
perhaps requiring a specific import to become visible)?
2. does this include — or are their separate plans for — exposing the backing 
reference type in some principled way? 

For (2.) what I mean is something like having at least the heavyweight thing 
like `Data` (and ideally also Array/Set/Dictionary/IndexSet, etc.) have 
matching-API reference types like `DataRef` in the standard library. 

I think this has come up before at some point, but if it did I didn’t follow it.

My interest in (1.) is mostly b/c I suspect the answer to (2.) is “no”.

Apologies if these are alrexdy-addressedd and I just missed it.

> On Apr 22, 2016, at 12:18 PM, Tony Parker via swift-evolution 
>  wrote:
> 
> Dear swift-evolution denizens,
> 
> As you know from our announcement of Swift Open Source and our work on naming 
> guidelines, one of our goals for Swift 3 is to “drop NS” for Foundation. We 
> want to to make the cross-platform Foundation API that is available as part 
> of swift-corelibs feel like it is not tied to just Darwin targets. We also 
> want to reinforce the idea that new Foundation API must fit in with the 
> language, standard library, and the rapidly evolving design patterns we see 
> in the community.
> 
> You challenged us on one part of this plan: some Foundation API just doesn’t 
> “feel Swifty”, and a large part of the reason why is that it often does not 
> have the same value type behavior as other Swift types. We took this feedback 
> seriously, and I would like to share with you the start of an important 
> journey for some of the most commonly used APIs on all of our platforms: 
> adopting value semantics for key Foundation types.
> 
> We have been working on this for some time now, and the set of diffs that 
> result from this change is large. At this point, I am going to focus effort 
> on an overview of the high level goals and not the individual API of each new 
> type. In order to focus on delivering something up to our quality standards, 
> we are intentionally leaving some class types as-is until a future proposal. 
> If you don’t see your favorite class on the list — don’t despair. We are 
> going to iterate on this over time. I see this as the start of the process.
> 
> One process note: we are still trying to figure out the best way to integrate 
> changes to API that ship as part of the operating system (which includes 
> Foundation) into the swift-evolution review process. Swift-evolution is 
> normally focused on changes to functionality in the compiler or standard 
> library. In general, I don’t expect all new Foundation API introduced in the 
> Darwin/Objective-C framework to go through the open source process. However, 
> as we’ve brought up this topic here before, I felt it was important to bring 
> this particular change to the swift-evolution list.
> 
> As always I welcome your feedback.
> 
> https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for-foundation.md
>  
> 
> 
> Thanks,
> - Tony
> 
> 
> 
> ___
> 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-0074: Implementation of Binary Search functions

2016-05-10 Thread plx via swift-evolution

> On May 9, 2016, at 10:28 PM, Nate Cook via swift-evolution 
>  wrote:
> 
>> On May 9, 2016, at 9:48 PM, Joe Groff via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On May 9, 2016, at 6:23 PM, Brent Royal-Gordon via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
 * Operations that depend on sorted-ness and use binary predicates should
 not be available on all Collections; they're too easy to misuse,
 they're hard to name well, and as Nicola Salmoria has noted, they
 would not make any sense at all for a Set.
 
 * They should be scoped to a kind of collection that bundles
 the predicate with the elements, e.g.
 
  let x = Sorted([3, 4, 1, 5, 2], >)  // stores a sorted copy of 
 the array
  let y = Sorted(preSorted: 0..<100, <)  // stores a copy of the range
 
 Maybe there should also be protocols for this; CountableRange would
 already already conform to the immutable version.  We might want a
 mutable form of the protocol for sorted collections with
 insertion/removal methods.  This whole area needs more design.
>>> 
>>> I agree with both of these statements, but not with your conclusion.
>>> 
>>> There are three classes of collections:
>>> 
>>> 1) Those which are always sorted, like a SortedSet.
>>> 2) Those which may or may not be sorted, like an Array.
>>> 3) Those which are never sorted, like a Set.
>>> 
>>> These APIs are useless on a #3, but #2 is still a valuable use case to 
>>> support. In particular, it's quite common to use sorted `Array`s, and these 
>>> APIs would help you do that.
>>> 
>>> What I might consider doing is tying this to `RangeReplaceableCollection`. 
>>> That protocol is applied only to types which allow insertion at arbitrary 
>>> indices, which is a good, though not perfect, proxy for types which might 
>>> allow you to manually maintain a sort order. `Array`, `ArraySlice`, 
>>> `ContiguousArray`, and the mutable `String` views would get these methods, 
>>> while `Set` and `Dictionary` would not.
>> 
>> We could also introduce a new OrderedCollection protocol. (This would also 
>> be useful in the future for supporting `case` pattern matching on 
>> collections. It makes sense to pattern-match arrays and other ordered 
>> collections in order by element, but you'd expect very different semantics 
>> pattern-matching an unordered Set.)

I have some high-level comments about this proposal: it feels rather muddled 
and as if it's mixing different concerns.

Taking a step back, at a *minimum* I think the right way to add this 
functionality is to:

A) add generic functions like `binarySearch` (etc.) to `Collection` (taking the 
GIGO risk, of course)
B) add overridable methods like `sortedIndex(of:)` to `Collection` (taking the 
GIGO risk again, of course)
C) provide default implementations of e.g. `sortedIndex(of:)` that use 
`binarySearch` (etc.)

…and *ideally* I think both (A) and probably (B) wind up introducing some 
methods like `_customBinarySearchForComparableElement` (etc.), but that is a 
level of detail that can be skipped for this discussion.

I understand the motivation to try and add only “intent-focused” methods like 
`sortedIndex(of:)`, but a binary search should be expressible generically and 
is a very useful building block to have when building such higher-level 
methods; it would also prove useful to *implement* the `Sorted(…)` concept 
mentioned above, one would think.

I also think it will be a mistake to restrict the availability of any of these 
APIs to “sorted” collections; there are several reasons here. 

One reason is simply b/c such sorted collections aren’t part of the standard 
library yet. 

Also, it seems like for *some* of these methods (binarySearch) it’s a category 
error to restrict them to sorted collections: such sorted collections should 
instead simply exploit their own ordering/structure where appropriate! 

Finally, things like binary searches are often basic building blocks (etc.) for 
*constructing* such ordered collections, and thus being unable to use them in 
that context would be limiting (e.g. if you wanted to implement `Sorted(…)` as 
suggested above, you’d probably benefit from being able to use these methods…).

Thus although I understand the desire for jumping immediately to the 
higher-level, "intent-focused” API, and although I understand the GIGO risk for 
having some of these methods defined too broadly, I am not sure the cures 
aren't worse than the disease here, so to speak.

>> 
> 
>> -Joe
> 
> Yet another alternative would be to drop Set and Dictionary down a level to a 
> FiniteSequence protocol in between Sequence and Collection. Basically none of 
> the index-based collection APIs (i.e. everything except `count` and 
> `isEmpty`) make sense on sets and dictionaries. index(where:) was marginally 
> useful with dictionaries, but now that Sequence is getting first(where:), née 
> find(...), even th

Re: [swift-evolution] (Draft) Add last(where:) and lastIndex(where:) methods

2016-05-10 Thread plx via swift-evolution
Do these return endIndex or nil on a not-found?

Either can work with different tradeoffs; depends on what you care about...but 
the choice should be justified and the alternative explained.

> On May 10, 2016, at 13:54, Nate Cook via swift-evolution 
>  wrote:
> 
> I've needed these in the past and used them in other languages—any feedback 
> on this  idea?
> 
> Add last(where:) and lastIndex(where:) Methods to Bidirectional Collections
> The standard library should include methods for finding the last element of a 
> bidirectional collection that matches a predicate, along with the index of 
> that element.
> 
> Motivation
> The standard library currently has (or will soon have) methods that perform a 
> linear search from the beginning of a collection to find an element that 
> matches a predicate:
> 
> let a = [20, 30, 10, 40, 20, 30, 10, 40, 20]
> a.first(where: { $0 > 25 }) // 30
> a.index(of: 10) // 2
> a.index(where: { $0 > 25 }) // 1
> Unfortunately, there is no such method that searches from the end of a 
> bidirectional collection. Finding the last of particular kind of element has 
> multiple applications, particularly with text, such as wrapping a long string 
> into lines of a maximum length or trimming whitespace from the beginning and 
> end of a string.
> 
> This limitation can be worked around by using the methods above on the 
> reversed collection, but the resulting code is truly dreadful. For example, 
> to find the corresponding last index to a.index(where: { $0 > 25 }), this 
> unholy incantation is required:
> 
> (a.reversed().index(where: { $0 > 25 })?.base).flatMap({ a.index(before: $0) 
> })
> Wat.
> 
> Proposed solution
> Bidirectional collections should include three new methods for symmetry with 
> the existing forward-searching APIs: last(where:), lastIndex(where:), and 
> lastIndex(of:), specifically for collections of Equatable elements.
> 
> These additions would remove the need for searching in a reversed collection 
> and allow code like the following:
> 
> a.last(where: { $0 > 25 })  // 40
> a.lastIndex(of: 10) // 6
> a.lastIndex(where: { $0 > 25 }) // 7
> Much better!
> 
> ___
> 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-0088: Modernize libdispatch for Swift 3 naming conventions

2016-05-13 Thread plx via swift-evolution

>   * What is your evaluation of the proposal?

+1 conceptually, some quibbles.

I agree with a few others that `synchronously` and `asynchronously` aren’t 
ideal; `dispatchSynchronously` or `dispatchSync` (or `performSync` or 
`performSynchronously`) all seem more-appropriate.

I understand the impetus behind having fewer core methods, but IMHO the 
`dispatch_barrier_sync` and `dispatch_barrier_async` calls ought to have direct 
equivalents here (even if they are just sodlib-supplied conveniences that call 
through to the unified method).

I also don’t see `dispatch_apply` here anywhere; intentional? Ideally it’d be 
@noescape, but handling `throw` / `rethrow` for that function in this case 
seems complicated.

This next one is subjective, but I find the placement of the group-related 
methods somewhat backwards vis-a-vis how I think of them in terms of the C-API.

EG: I think of `dispatch_group_async` as a “method” on a `dispatch_group`, so 
would’ve expected this:

class DispatchGroup : DispatchObject {

  // (actual name should match chosen name convention)
  func asynchronouslyDispatch(to queue: DispatchQueue, work: @convention(block) 
() -> Void)

  // (actual name should match chosen name convention)
  func notify(on queue: DispatchQueue, using block: @convention(block) () -> 
Void)

}

…(and presumably the API would have manual enter/leave/wait methods and so on 
exposed).

I don’t feel strongly here but bring it up in case others feel similarly.

I’m a little confused about the `DispatchSpecificKey` class; is it anything 
more than a way to "smuggle in” a generic type parameter for the associated 
value? 

Also on queue-specifics, what is our expected story if we have custom 
destructors? Subclass `DispatchSpecificKey`? 

For things like `Int` specifics, I assume this API is storing auto-boxed 
values…? Is there any way to side-step if we use want to store an unsafe 
pointer? It’s not a big deal for me if we can’t under this API, TBH, but I’d at 
least like to see this API’s implementation and costs spelled-out more 
explicitly.

For `DispatchData`, is there a principled reason there isn’t something like 
this defined:

struct DispatchDataSegment {
  let bytes: UnsafeBufferPointer
  let byteIndex: Int
}

extension DispatchData {

  /// Returns a sequence that enumerates the contiguous chunks,
  /// e.g. a sequence with elements of type `DispatchDataSegment`.
  ///
  /// Sequence-based eplacement-for `enumerateBytes(_:)`
  var segmentSequence: DispatchDataSegmentSequence { get }

}

…or something analogous (instead of the proposed use dispatch_data_apply?)? 

I don’t see any API yet for setting target queues, or getting queue labels. I 
know the proposal isn’t documenting the APIs in full but it’s hard to evaluate 
in that absence.

I don’t see basic API on dispatch sources yet for things like setting event 
handlers, (etc.); again I know the APIs aren’t fully specified here but it’s 
hard to evaluate something that’s not fully specified.


>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0081: Move where clause to end of declaration

2016-05-17 Thread plx via swift-evolution
Late, but +1 *overall*.

For function signatures I am somewhat indifferent, honestly; I think having the 
option to move part of the `where` clause after the signature declaration is 
beneficial, but not hugely so.

The reasoning here is simple: currently functions look like `func 
$name<$genericParameters>($args) -> $result`, and even though it’s difficult to 
*read* a lengthy `$genericParameters` the `($args) -> $result` portion (e.g. 
signature) isn’t "broken up". It’s good that it’s not broken up, but it means 
for *functions* the proposal is making only a minor readability improvement (by 
moving the “signature" closer to the “name”).

But, I think we have a *significant* improvement here for *type* declarations — 
classes, structs, etc. — because they look like e.g. this for classes: `class 
$name<$genericParameters> : $base (, … $protocols )`. If one is writing classes 
that use a lot of generic parameters with a lot of relationships between their 
associated types, the key parts of the type declaration wound up “split up” b/c 
the `$name` is very far away from the `$base`.

It’s apparently a somewhat-uncommon use but it’s *a lot nicer* under this 
proposal than under current syntax.

I wouldn’t object if the proposal tried to be a bit less flexible and e.g. 
forced all `:`-style constraints into the initial `<>` segment and all `where 
X.Y == Z.Q`-style constraints into the subsequent `where` clause, but I also 
don’t feel that that would be an unqualified improvement.

> On May 10, 2016, at 1:51 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0081: Move where clause to end of declaration" begins now 
> and runs through May 16. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0081-move-where-expression.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0091: Improving operator requirements in protocols

2016-05-18 Thread plx via swift-evolution
Mixed; there are very good ideas here but combined in IMHO some 
questionably-strict ways. I understand that starting small and extending later 
is preferable, and I understand the Swift 3 situation.

In favor of these: 
- allowing static methods to have “operator names”
- deprecating operator requirements in protocols
- providing default operator definitions as trampolines to the static methods

It’s really not clear to me if this is anything more than just:

- adding the ability to give (static/class) methods operator names
- removing the ability for protocols to declare operators
- make all operator implementations “explicit"…
- ...but providing “protocol operators” generically (e.g. via suitable 
“trampolines”)

…if that’s all there is to this, I’m ok with it for now, but have a suggestion:

I’d *prefer* there be an explicit annotation, e.g. to straw-man it a bit, 
something like one of these:

  @trampolined static func +(lhs: Self, rhs: Self) -> Self
  @trampolined(operator) static func +(lhs: Self, rhs: Self) -> Self

…which for now would just produce a compiler warning if no corresponding 
operator function is defined, but could someday be used to trigger trampoline 
synthesis.

The reason I request explicit syntax for this is b/c it seems *highly* likely 
that a subsequent enhancement will be to allow a similar mechanism to specify 
functions like `abs` and `sin` should be similarly trampolined (in their case 
into free functions); it’d be nice to have a common mechanism for them now, 
even if their implementation is to be deferred. 

That said, it’d *concern me* if this proposal somehow planned to enforce that 
“operators” *always* call through to the operator-named function; it ought to 
be possible to e.g. define operators like so:

  protocol AngularCoordinateProtocol {

associatedtype Rotation: RotationProtocol

static func rotated(angle angle: Self, by rotation: Self.Rotation) -> Self

  }

  func +(lhs: A, rhs: A.Rotation) -> A { return 
A.rotated(angle: lhs, by: rhs) }
  func -(lhs: A, rhs: A.Rotation) -> A { return 
A.rotated(angle: lhs, by: -rhs) }

…and it seems like this proposal wouldn’t preclude that, but I’m not 100% I 
understand it on that point. 

Also, I can’t say I’m a fan of having the prefix/postfix handled by argument 
labels.

How hard would it be to e.g. simply allow something like this:

  func ==(lhs: T, rhs: T) -> Bool {
return lhs T.== rhs
  }

…instead of the `T.==(lhs,rhs)` syntax?

> On May 17, 2016, at 10:33 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0091: Improving operator requirements in protocols" begins 
> now and runs through May 23. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0091-improving-operators-in-protocols.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] SE-0089: Renaming String.init(_: T)

2016-05-20 Thread plx via swift-evolution

> On May 19, 2016, at 5:57 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> on Tue May 17 2016, Chris Lattner  > wrote:
> 
>> Hello Swift community,
>> 
>> The review of "SE-0089: Renaming String.init(_: T)" begins now and
>> runs through May 23. The proposal is available here:
>> 
>>  
>> https://github.com/apple/swift-evolution/blob/master/proposals/0089-rename-string-reflection-init.md
>> 
>> Reviews are an important part of the Swift evolution process. All
>> reviews should be sent to the swift-evolution mailing list at
>> 
>>  https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> or, if you would like to keep your feedback private, directly to the review 
>> manager.
>> 
>> What goes into a review?
>> 
>> The goal of the review process is to improve the proposal under review
>> through constructive criticism and contribute to the direction of
>> Swift. When writing your review, here are some questions you might
>> want to answer in your review:
>> 
>>  * What is your evaluation of the proposal?
>>  * Is the problem being addressed significant enough to warrant a change 
>> to Swift?
>>  * Does this proposal fit well with the feel and direction of Swift?
>>  * If you have used other languages or libraries with a similar
>> feature, how do you feel that this proposal compares to those?
>>  * How much effort did you put into your review? A glance, a quick 
>> reading, or an in-depth study?
>> 
>> More information about the Swift evolution process is available at
>> 
>>  https://github.com/apple/swift-evolution/blob/master/process.md
> 
> I'm posting this on behalf of Dmitri Gribenko, and Max Moiseev, and
> myself.
> 
> We would like to accept the proposal with one modification: rather than
> add an argument label, we'd like to drop the String initializer
> altogether, making `"\(expression)"` the standard way to get a string
> representation of `expression`.

Is there some performance-driven motivation here, or is this just aesthetics?

I ask b/c not having a name for this "initializer" here would seem mildly 
annoying and asymmetric vis-a-vis `String.init(reflecting:)`; sure, I can 
always add an equivalent with a name, but I’m curious if there’s an 
argument-from-functionality for the removal.

Also FWIW I like the idea to use `init(describing:)`, although it’s still a bit 
quirky when put side-by-side with `init(reflecting:)` (since it doesn’t really 
capture the heart of the distinction between the two, IMHO).

> 
> Thanks,
> 
> -- 
> -Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0117: Default classes to be non-subclassable publicly

2016-07-06 Thread plx via swift-evolution
+1 except for the choice of names if I understand it correctly, but I want to 
make sure I understand it correctly.

The scenario I want to to make sure I understand is what happens for a 
class-cluster type pattern like the following:

  // Module A:
  public class PublicBaseClass {
func someMethod() { /* placeholder here */ }
  }

  private class PrivateSubclass : PublicBaseClass {
override func someMethod() { /* new logic here */ }
  }

…I think this would make `PublicBaseClass` effectively “final” (e.g. 
non-subclassable) from outside of Module A, but `PrivateSubclass` (and similar 
constructs, etc.) would still be allowed and work as one would expect?

If so, that’s what I’d want semantically, so +1 on that for the semantics.

*But*, that behavior means that it is *very* confusing to be using 
`subclassable` and `overridable` for what they mean in this protocol.

I usually stay out of bike shedding but these attributes are really poorly 
named IMHO; I’d *highly recommend* something like either the ugly-but-explicit 
`externally_subclassable` / `externally_overrideable` or something else 
entirely (like maybe `open`?) that avoids the confusion.

Apologies if this has already come up or is based upon a misunderstanding of 
the proposal.

> On Jul 5, 2016, at 6:11 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "SE-0117: Default classes to be non-subclassable publicly" 
> begins now and runs through July 11. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0117-non-public-subclassable-by-default.md
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and contribute to the direction of Swift. When 
> writing your review, here are some questions you might want to answer in your 
> review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Chris Lattner
> Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Dropping Comparable requirement for indices

2016-07-06 Thread plx via swift-evolution
My own 2c is to drop the comparable requirement.

I can elaborate if necessary, but wanted to at least cast my “+1” for removing 
the requirement.

> On Jul 5, 2016, at 9:39 PM, Dave Abrahams via swift-evolution 
>  wrote:
> 
> 
> I've already raised the question here of whether we should weaken the
> requirement that Collection.Index be Comparable to merely being
> Equatable.  
> 
> Part of the motivation was to support data structures that otherwise
> would be expensive or impossible to implement.  For example, with
> Comparable indices, you can't build a linked list that supports
> restructuring (e.g. insert, delete, splice) in O(1) without invalidating
> indices... not even an unsafe linked list with reference semantics.
> [While I don't think linked lists are terribly good data structures for
> most things, they are still useful in teaching, and it bothered me that
> we were ruling them out.]  Even if you take away the index invalidation
> restriction, you have to store a counter in the index, which is an awkward 
> inefficiency.
> Supporting Comparable indices for a tree data structure requires
> encoding the path from the root to the node.  It's only one or two words
> in practice, but it's another awkward inefficiency.
> 
> Over the weekend, I tried lifting the restriction to see what kind of
> effect it would have on the standard library.
> https://github.com/apple/swift/pull/3325
> 
> Although I *had* been leaning strongly toward making this change, having
> looked at the effects, I am now more ambivalent:
> 
> * A Range, where T is not Comparable, could be constructed with any
>  pair of Equatable T instances.  We'd only detect that the Range may be
>  invalid when T happened to also be Comparable.  However, the fact that
>  you are creating a Range already sort of implies an underlying
>  ordering.
> 
> * A Collection with non-Comparable indices still imposes an ordering
>  upon the indices.
> 
> * In a Collection with Comparable indices, the ordering implied by <
>  needs to match the ordering of indices in the collection.  Otherwise,
>  there would be no way to form Ranges (for use in slicing, for example)
>  without causing a trap.  This is *weird*!  There's little precedent
>  for imposing stronger semantic requirements on an associated type if
>  it conforms to a particular protocol (Comparable in this case), except
>  where the requirement is part of the protocol.
> 
> Also, Dmitri reminded me that even with a Comparable requirement on
> indices, there is still no problem converting an equatable iteration
> state into an index; you just need to augment it with an integer
> counter.  So it's still trivial to create a Collection from nearly
> everything that is today a multipass Sequence.  It does make indexing
> slightly more expensive, but it's likely we'd optimize that overhead
> away in many critical situations.
> 
> Anyway, the thoughts of the community on this topic would be interesting
> to us.  We need to make a decision about this very soon.
> 
> Thanks!
> 
> -- 
> Dave
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution


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


Re: [swift-evolution] Dropping Comparable requirement for indices

2016-07-08 Thread plx via swift-evolution

> On Jul 6, 2016, at 7:33 PM, Xiaodi Wu  wrote:
> 
> I for one would be interested in your elaboration. Based on Dave's comments, 
> I'm pretty convinced that the Comparable requirement is best left in place.

I am short on time (and will remain so for several more weeks) so this should 
be seen as essentially a fire-and-forget message. 

I'll preface the rest with the disclaimer that I don't think any of the 
assessments already made are *wrong* on the facts...I simply (a) disagree on 
what to make of them and also (b) think there is more cost to requiring  
`Comparable` than has been noted so far.

For (a), I agree with the following pair of facts:

- there are "collections" for which the "natural" choice of index is awkward to 
make `Comparable` (thus making conformance to `Collection` awkward)...
- such "non-comparable indices" can easily be made comparable when needed, e.g. 
by stapling an `Int` onto each "natural" index (or via some similar 
augmentation)

...but to me this argues in favor of dropping the requirement:

- dropping it allows more "collections" to become proper `Collection`s (while 
still using the "natural" index)
- when you specifically need comparable indices, they are easy to add (so why 
not *not* pay for comparability except when you specifically need it)

For (b), I think that the long-term costs of techniques like "`Int`-stapling" 
are actually rather more severe than just the overhead of the stapled-on `Int` 
(etc.); to illustrate this, consider linked-lists, since they've already been 
brought up.

I'll state without proof that the following are reasonable:

- if we only need `Equatable` indices:
  - the list nodes are the natural choice of "index"
  - the list nodes are *robust* indices (very few updates invalidate them)
- if we instead need `Comparable` indices:
  - the easiest index is a pair like `(list-node, counter)`
  - these indices are *fragile* indices (invalidated after most updates)

...and proceed to my point:

It's not hard to imagine at some point introducing a protocol for a mutable 
collection with *robust* indices -- e.g., behaving like the "natural" indices 
we could get away with here if we only needed `Equatable` -- and providing 
either (or both):

- improved generic implementations of standard mutation operations
- additional mutation operations that are only practical with robust indices

...and the unfortunate consequence of the `Comparable`-index requirement is 
that our linked-list would **not** be able to adopt such a protocol -- and 
benefit from such algorithms, etc. -- b/c that requirement means that the 
`Index` it will expose in a generic setting is the more-fragile, “stapled 
index” instead of the more-robust, “natural index” we could have used 
otherwise. 

This has been discussing linked-lists but I think it generalizes; e.g. for 
other things that “could be ‘collections’” without the `Comparable`-`Index` 
requirement, you can easily make indices that *do* satisfy the `Comparable` 
requirement…at the cost of winding up with comparatively-fragile indices that 
are a bit pessimal for use with mutation operations. I’ll speculate that the 
issues being alluded-to for trees are roughly similar: it’s not that it’s hard 
to make the tree indices comparable, it’s that there’s no good way to do that 
without making the resulting indices “artificially” fragile.

And so on. 

So to conclude, I don’t really disagree that the issues raised by 
non-comparable indices are real issues, but I *do* think the cost/benefit 
analysis should include the cost of having "locked-in" the use of fragile, 
easily-invalidated indices vis-a-vis what might otherwise have been used. It’s 
not amazingly convincing without more-concrete examples, but this is all I have 
time for. 
___
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-28 Thread plx via swift-evolution
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?

> On Sep 26, 2016, at 7:18 PM, Douglas Gregor via swift-evolution 
>  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.
> 
> Swift-evolution thread: TBD: Discussion thread topic for that proposal 
> 
>  
> Motivation
> 
> Conditional conformances address a hole in the composability of the generics 
> system. Continuing the Array example from above, it's always been the case 
> that one could use the == operator on two arrays of Equatable type, e.g., 
> [Int]() == [Int]() would succeed. However, it doesn't compose: arrays of 
> arrays of Equatable types cannot be compared (e.g.,[Int] 
> ==
>  [Int] 
> will
>  fail to compile) because, even though there is an==for arrays of 
> Equatabletype, the arrays themselves are neverEquatable`.
> 
> Conditional conformances are particularly powerful when building generic 
> adapter types, which are intended to reflect the capabilities of their type 
> arguments. For example, consider the "lazy" functionality of the Swift 
> standard library's collections: using the lazy member of a sequence produces 
> a lazy adapter that conforms to the Sequence protocol, while using the lazy 
> member of a collection produces a lazy adapter that conforms to the 
> Collection protocol. In Swift 3, the only way to model this is with different 
> types. For example, the Swift standard library has four similar generic types 
> to handle a lazy collection: LazySequence, LazyCollection, 
> LazyBidirectionalCollection, and LazyRandomAccessCollection. The Swift 
> standard library uses overloading of the lazy property to decide among these:
> 
> extension Sequence {
>   var lazy: LazySequence { ... }
> }
> 
> extension Collection {
>   var lazy: LazyCollection { ... }
> }
> 
> extension BidirectionalCollection {
>   var lazy: LazyBidirectionalCollection { ... }
> }
> 
> extension RandomAccessCollection {
>   var lazy: LazyRandomAccessCollection { ... }
> }
> This approach causes an enormous amount of repetition, and doesn't scale well 
> because each more-capable type has to re-implement (or somehow forward the 
> implementation of) all of the APIs of the less-capable versions. With 
> conditional conformances, one can provide a single generic wrapper type whose 
> basic requirements meet the lowest common denominator (e.g., Sequence), but 
> which scale their capabilities with their type argument (e.g., the 
> LazySequence conforms to Collection when the type argument does, and so on).
> 
>  
> Proposed
>  solution
> 
> In a nutshell, the proposed solution is to allow a constrained extension of a 
> struct, enum, or class to declare protocol conf

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

2016-09-28 Thread plx via swift-evolution
+1 to have something *like* this, but a few questions.

Is there a specific reason `IndexedSequence` isn’t `IndexedCollection`, 
conforming to `Collection` (and once conditional conformances are available 
picking up `BidirectionalCollection` and `RandomAccessCollection` when 
possible?).

Secondly, can you provide more detail on the proposed implementation? 

Are you just walking the index forward and subscripting the base in the 
iterator, or something fancier?

> On Sep 28, 2016, at 12: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


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

2016-09-28 Thread plx via swift-evolution

> On Sep 28, 2016, at 4:47 PM, Kevin Ballard  wrote:
> 
> On Wed, Sep 28, 2016, at 02:27 PM, plx via swift-evolution wrote:
>> +1 to have something *like* this, but a few questions.
>> 
>> Is there a specific reason `IndexedSequence` isn’t `IndexedCollection`, 
>> conforming to `Collection` (and once conditional conformances are available 
>> picking up `BidirectionalCollection` and `RandomAccessCollection` when 
>> possible?).
> 
> This is already being discussed in this thread, but the simple answer is that 
> adds complexity and it's not obvious that it's worth the additional 
> complexity.

As it can be done as trivial, "pass-through" boilerplate:

  struct IndexedCollection :Collection {
typealias Index = C.Index
typealias Indices = C.Indices

let base: C
  
subscript(i: Index) -> (Index,C.Iterator.Element) { return (i,base[i]) }
  
}

…(and so on and so forth) it’s about as trivial to implement as any 
`Collection` is going to be…which is why I was a bit surprised it wasn’t part 
of the proposal.

If you’re worried about performance vis-a-vis lazy collections you could also 
store the `base.indices` and use it instead of `base` but even that should 
leave the implementation almost entirely boilerplate-ish.

Sure it’s a bit annoying to write it all out but I’m not seeing a lot of 
complexity really; I might be missing something?

> 
>> Secondly, can you provide more detail on the proposed implementation? 
>> 
>> Are you just walking the index forward and subscripting the base in the 
>> iterator, or something fancier?
> 
> Yeah, that's what it would be. Something like
> 
> sequence(state: base.indices, next: {
> guard let idx = $0.next() else { return nil }
> return (idx, base[idx])
> })
> 
> except done as a concrete type.

I assume the above is closer to this?

> sequence(state: base.indices.makeIterator(), next: {
> guard let idx = $0.next() else { return nil }
> return (idx, base[idx])
> })

The way the proposal was worried I was concerned the “only calculate each index 
once” bit would be a bit expensive when not really necessary, but deferring to 
the implementation of `indices` seems perfectly reasonable to me.

> 
> -Kevin
> 
>>> On Sep 28, 2016, at 12:55 PM, Erica Sadun via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> Gist here: https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2 
>>> <https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2>
>>> 
>>> Introducing indexed() collections
>>> 
>>> Proposal: TBD
>>> Author: Erica Sadun <https://github.com/erica>, Nate Cook 
>>> <https://github.com/natecook1000>, Jacob Bandes-Storch 
>>> <https://github.com/jtbandes>, Kevin Ballard <https://github.com/kballard>
>>> Status: TBD
>>> Review manager: TBD
>>>  
>>> <https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2#introduction>Introduction
>>> 
>>> This proposal introduces indexed() to the standard library, a method on 
>>> collections that returns an (index, element) tuple sequence.
>>> 
>>> Swift-evolution thread: TBD <https://gist.github.com/erica/tbd>
>>>  
>>> <https://gist.github.com/erica/2b2d92e6db787d001c689d3e37a7c3f2#motivation>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 p

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- 
>>> <https://github.com/DougGregor/swift-evolution/blob/conditional-conformances/proposals/-conditional-conformances.md>
>>> Author: Doug Gregor <https://github.com/DougGregor>
>>> Review Manager: TBD
>>> Status: Awaiting review
>>> During the review process, add the following fields as needed:
>>> 
>>> Decision Notes: Rationale 
>>> <https://lists.swift.org/pipermail/swift-evolution/>, Additional Commentary 
>>> <https://lists.swift.org/pipermail/swift-evolution/>
>>> Bugs: SR- <https://bugs.swift.org/browse/SR->, SR- 
>>> <https://bugs.swift.org/browse/SR->
>>> Previous Revision: 1 
>>> <https://github.com/apple/swift-evolution/blob/...commit-ID.../proposals/-filename.md>
>>> Previous Proposal: SE- 
>>> <https://github.com/DougGregor/swift-evolution/blob/conditional-conformances/proposals/-filename.md>
>>>  
>>> <https://github.com/DougGregor/swift-evolution/tree/conditional-conformances#introduction>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

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

2016-10-02 Thread plx via swift-evolution

> On Sep 30, 2016, at 1:23 PM, Douglas Gregor  wrote:
>> 
>> 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!

I've taken the time to provide a bit more color on the 80/15/5 breakdown 
because I don't see much discussion for this proposal in terms of concrete 
situations...just theoretical concerns and theoretical possibilities. I don't 
have any completed code either, but I have notes and to-do lists for things I 
was planning to do, and I think seeing even some semi-concrete scenarios might 
be helpful here.

The "80%" are generally analogous to the `SomeWrapper` in the writeup; as a 
concrete example, I was waiting on the availability of conditional conformances 
to resume work on an emulation of structural unions, e.g. something like:

  enum Sum2 {
case a(A)
case b(B)
  }
  
...(and analogously for 3, 4, as-necessary). 

There's a very obvious way to write `extension Sum2 : Equatable where 
A:Equatable, B:Equatable {}`...and at the time I set this aside, I was 
expecting to also want to come back and have additional conformances for things 
like `...where A:Equatable, B:AnyObject` (using `===` for comparing `B`) and so 
on for other combinations.

Upon revisiting such things in light of the proposal, I now think differently: 
for this case it seems like a better long-term approach anyways to stick to a 
single conformance and work with it like this:

  extension Sum2:Equatable where A:Equatable, B:Equatable {
// details elided
  }
  
  /// Adaptor using `ObjectIdentifier` to implement `==`.
  struct ObjectWrapper : Equatable, Hashable {
let wrapped: Wrapped
  }
  
...as upon reflection I really would prefer dealing with the hassle of working 
with `Sum2>` in situations where -- in theory -- `Sum2` 
could do -- to the hassle of writing out 4+ conformances for `Sum2` (and so 
on...even with nice code-gen tools that's going to be a lot of bloat!). 

What changed my mind was tracing through the implications of conditional 
conformances for the use-site ergonomics of adaptors like `ObjectWrapper` 
above; what I mean is, suppose I have a protocol like this:

  protocol WidgetFactory {
associatedtype Widget
associatedtype Material

func produceWidget(using material: Material) -> Widget
  }

...then it's rather easy to simply write this type of boilerplate:

  extension ObjectWrapper: WidgetFactory where Wrapped: WidgetFactory {
typealias Widget = Wrapper.Widget
typealias Material = Wrapper.Material

func produceWidget(using material: Material) -> Widget {
  return base.produceWidget(using: material)
}
  }
  
...which thus means I have the tools I need to make my use of wrappers like the 
`ObjectWrapper` largely transparent at the use sites I care about; e.g. I can 
write a single conditional conformance like this:

  extension Sum2: WidgetFactory 
where 
A:WidgetFactory, B:WidgetFactory,
A.Material == B.Material,
A.Widget == B.Widget {

typealias Widget = A.Widget
typealias Material = A.Material

func produceWidget(using material: Material) throws -> Widget {
  switch self {
case let .a(aa): return aa.produceWidget(using: material)
case let .b(bb): return bb.produceWidget(using: material)
  }
}

  }
  
...and it will apply even in situations where circumstances left me using 
`ObjectWrapper` (or similar) on any of the type parameters to `Sum2` (e.g. if I 
also needed an `Equatable` conformance for whatever reason).

At least for now--when I'm still just revisiting plans and thinking about it in 
light of the proposal--I really would prefer having a simpler language and 
writing this type of boilerplate, than having a more-complex language and 
writing the *other* type of boilerplate (e.g. the 4+ `Equatable` conformances 
here, and so on for other situations).

Note that I'm not claiming the above is the only use for overlapping 
conditional conformances -- not at all! -- just that situations like the above 
comprise about 80% of the things I was intending to do with conditional 
conformances...and that after revisiting them ex

Re: [swift-evolution] [Proposal Draft] Provide Custom Collections for Dictionary Keys and Values

2016-10-12 Thread plx via swift-evolution
The issue addressed is real; I’m not sure this is the best approach. 

In particular, unless I’m missing something obvious, the ownership strategy 
here would have to be:

- `DictionaryKeys` and `DictionaryValues` would each induce the expected +1 
retain on the underlying storage
- `DictionaryValues`’s mutations avoid triggering COW on the underlying storage 
by skipping the usual ownership check

…as otherwise it’s unclear how you’d do those in-place mutations (and this 
seems to be how the implementation works...is that correct?).

With that design, it seems like you’d wind up allowing things like the below:

  // example A
  let foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
  let bar = foo // shared storage, no COW
  foo.values[foo.index(of: “abc”)!].append(789) // update shared storage, no COW

  // shared storage mutated,
  // despite (a) both being `let` and (b) only foo.values getting touched
  foo[“abc”] // [1, 2, 3, 789]
  bar[“abc”] // [1, 2, 3, 789]

  // example B
  var foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
  var bar = foo // shared storage, no COW
  foo.values[foo.index(of: “abc”)!].append(789)

  // shared storage mutated only foo.values getting touched
  foo[“abc”] // [1, 2, 3, 789]
  bar[“abc”] // [1, 2, 3, 789]

  // example C
  var foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
  var bar = foo 
  bar[“abc”] = [1, 2, 3, 4] // COW triggered here, no shared storage
  foo.values[foo.index(of: “abc”)!].append(789)

  // only `foo`’s storage mutated, b/c change to `bar` triggered COW
  foo[“abc”] // [1, 2, 3, 789]
  bar[“abc”] // [1, 2, 3, 4]

…where both A (by itself) and the B/C contrast seem very unwelcome.

Also, even if we assume we only ever make *responsible* use, having the stdlib 
include such directly-mutating views would seem likely to complicate any future 
concurrency plans.

To reiterate, I think the issue being addressed here is extremely important…I 
just don’t think I can get behind this type of solution (unless I’m grossly 
misunderstanding its mechanics).

> On Oct 11, 2016, at 4:28 PM, Nate Cook via swift-evolution 
>  wrote:
> 
> Introduction
> 
> This proposal addresses significant unexpected performance gaps when using 
> dictionaries. It introduces type-specific collections for a Dictionary 
> instance's keys and values properties.
> 
> New DictionaryKeys and DictionaryValues collections provide efficient key 
> lookup and mutable access to dictionary values, enabling updates to be 
> performed in-place and allowing copy-on-write optimization of stored values.
> 
>  
> Motivation
> 
> This proposal address two problems:
> 
> The Dictionary type keys implementation is inefficient, because 
> LazyMapCollection doesn't know how to forward lookups to the underlying 
> dictionary storage.
> Dictionaries do not offer value-mutating APIs. The mutating key-based 
> subscript wraps values in an Optional. This prevents types with copy-on-write 
> optimizations from recognizing they are singly referenced.
> This proposal uses the following [String: [Int]] dictionary to demonstrate 
> these problems:
> 
> var dict = ["one": [1], "two": [2, 2], "three": [3, 3, 3]]
>  
> Inefficient
>  dict.keys Search
> 
> Swift coders normally test key membership using nil checks or underscored 
> optional bindings:
> 
> if dict["one"] != nil {
> // ...
> }
> if let _ = dict["one"] {
> // ...
> }
> These approaches provide the expected performance of a dictionary lookup but 
> they read neither well nor "Swifty". Checking keys reads much better but 
> introduces a serious performance penalty: this approach requires a linear 
> search through a dictionary's keys to find a match.
> 
> if dict.keys.contains("one") {
> // ...
> }
> A similar dynamic plays out when comparing dict.index(forKey:) and 
> dict.keys.index(of:).
> 
>  
> Inefficient
>  Value Mutation
> 
> Dictionary values can be modified through the keyed subscript by direct 
> reassignment or by using optional chaining. Both of these statements append 1 
> to the array stored by the key "one":
> 
> // Direct re-assignment
> dict["one"] = (dict["one"] ?? []) + [1]
> 
> // Optional chaining
> dict["one"]?.append(1)
> Both approaches present problems. The first is complex and hard to read. The 
> second ignores the case where "one" is not a key in the dictionary. It forces 
> its check into a higher branch and encourages forced unwrapping. Furthermore, 
> neither approach allows the array to grow in place. They introduce an 
> unnecessary copy of the array's contents even though dict is the sole holder 
> of its storage.
> 
> Adding mutation to a dictionary's index-based subscripting isn't possible. 
> Changing a key stored at a particular index would almost certain

Re: [swift-evolution] [Proposal Draft] Provide Custom Collections for Dictionary Keys and Values

2016-10-12 Thread plx via swift-evolution
Thanks for the quick reply; given that I’m quite wrong about the important 
mechanics I rescind my criticisms.

I will say I care about this enough to reply because the inability to do 
in-place mutation of dictionary values has been an incredibly frustrating 
limitation and I’d just assumed the situation with slices/views would 
necessarily have similar issues for similar reasons…but glad to learn it’s not 
what I thought!

That said, I think efficient in-place mutation is too important to only expose 
so implicitly (seemingly due to the compiler eliding the otherwise-expected 
retain increments when the view is sufficiently “transient”…which seems like 
you perhaps can’t have an "in-place capable" view that’s implemented as a 
class, I’d think).

But none of this impacts my change to being in support for the proposal.

> On Oct 12, 2016, at 10:07 AM, Nate Cook  wrote:
> 
> 
>> On Oct 12, 2016, at 9:32 AM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> The issue addressed is real; I’m not sure this is the best approach. 
>> 
>> In particular, unless I’m missing something obvious, the ownership strategy 
>> here would have to be:
>> 
>> - `DictionaryKeys` and `DictionaryValues` would each induce the expected +1 
>> retain on the underlying storage
>> - `DictionaryValues`’s mutations avoid triggering COW on the underlying 
>> storage by skipping the usual ownership check
>> 
>> …as otherwise it’s unclear how you’d do those in-place mutations (and this 
>> seems to be how the implementation works...is that correct?).
> 
> That's not quite right—when you access these views through the dictionary, 
> they do not increment the storage retain count. This is the way slicing and 
> views currently work on other mutable types. For example, when you reverse a 
> slice of an array in-place, the slice doesn't get its own duplicate storage:
> 
> var a = Array(1...10)
> a[0..<5].reverse()
> a == [5, 4, 3, 2, 1, 6, 7, 8, 9, 10]
> 
> However, if you create a new variable out of the slice and reverse that, the 
> slice does get its own storage:
> 
> var b = Array(1...10)
> var bSlice = b[0..<5]
> bSlice.reverse()
> bSlice == [5, 4, 3, 2, 1]
> b == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
> 
> Strings and their views work the same way:
> 
> var s = "abcdefg"
> s.characters.append("H")   // storage updated in place
> s == "abcdefgH"
> 
> var sChars = s.characters  // no copy yet
> sChars.removeLast() // sChars gets its own copy before the mutation
> s == "abcdefgH"
> String(sChars) == "abcdefg"
> 
> var t = s   // no copy yet
> t.characters.removeLast()  // t gets a new copy here
> s == "abcdefgH"
> t == "abcdefg"
> 
> I don't know the name of the compiler feature that enables this, but it's a 
> critical part of the way views and slices work.
> 
>> With that design, it seems like you’d wind up allowing things like the below:
>> 
>>   // example A
>>   let foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
>>   let bar = foo // shared storage, no COW
>>   foo.values[foo.index(of: “abc”)!].append(789) // update shared storage, no 
>> COW
>> 
>>   // shared storage mutated,
>>   // despite (a) both being `let` and (b) only foo.values getting touched
>>   foo[“abc”] // [1, 2, 3, 789]
>>   bar[“abc”] // [1, 2, 3, 789]
> 
> Example A isn't allowed—if foo and bar are both immutable, both of their 
> `values` collections are also immutable, so there's no way to modify their 
> shared storage.
> 
>>   // example B
>>   var foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
>>   var bar = foo // shared storage, no COW
>>   foo.values[foo.index(of: “abc”)!].append(789)
>> 
>>   // shared storage mutated only foo.values getting touched
>>   foo[“abc”] // [1, 2, 3, 789]
>>   bar[“abc”] // [1, 2, 3, 789]
> 
> Example B is incorrect—the mutation at `foo.values[...].append(789)` triggers 
> a copy of the entire dictionary's underlying storage before allowing the 
> mutation, since it knows that storage isn't uniquely referenced.
> 
>>   // example C
>>   var foo = [ “abc”: [1,2,3], “efg”: [4,5,6] ]
>>   var bar = foo 
>>   bar[“abc”] = [1, 2, 3, 4] // COW triggered here, no shared storage
>>   foo.values[foo.index(of: “abc”)!].append(789)
>> 
>>   // only `foo`’s storage mutated, b/c change to `bar` triggered COW
>>   foo[“abc”] // [1, 2, 3, 789]
>>   bar[“abc”] // [1, 2, 3, 4]
> 
> This is the current behavior and would remain the same after the proposed the 
> changes.
> 
&

Re: [swift-evolution] [Proposal Draft] Provide Custom Collections for Dictionary Keys and Values

2016-10-12 Thread plx via swift-evolution
I agree that at least for stdlib purposes there’s something that looks like an 
explicit choice to make in-place mutation *available*. 

What I was trying to explain is whether or not in-place mutation *happens* is a 
bit implicit. It’s one thing to say that the difference here is just an idiom 
to know:

  var foo = [0, 1, 2, 3, 4, 5]
 
  // not in place:
  var slice = foo[1…3]
  slice.reverse() // `foo` not mutated

  // in place:
  foo[1…3].reverse() // `foo` mutated 

…but whether or not this function triggers an in-place mutation:

  func reverse(_ slice: inout ArraySlice) { 
   slice.reverse() 
  }

…depends on how it’s being called:
 
  var slice = foo[1…3]
  reverse(&slice) // `foo` unchanged
  
  reverse(&foo[1…3]) // `foo` mutated in-place

This seems consistent with the “in-place…or not?” behavior being largely just 
the usual COW, + the compiler eliding the typical retain/release on any 
sufficiently-transient slices; e.g. as if:

  // in place:
  foo[1…3].reverse() // `foo` mutated 

  // is treated as the equivalent of:
  @noretain var slice = foo[1…3]
  slice.reverse()

…where the @noretain is some (fictional) attribute suppressing the 
retain/release you’d otherwise trigger when `foo[1…3]` is stored into `slice`.

That’s the mental model it suggests, at least…and it just seemed unlikely that 
the compiler would be able to propagate something like `@noretain` onto a 
specific instance variable in a specific instance of a class-based view that 
captured a reference to the viewed collection’s underlying storage…whence the 
comment about class-based views. But I’ve been very wrong already today and 
probably am here as well.

As this is getting off-topic for something that seems like it’ll get postponed 
until later anyways I’d just like to say thanks again for taking the time to 
propose this, for correcting my misunderstandings…and that I’m eagerly looking 
forward to any improvements into COW visibility and any steps towards having 
more-explicit control over the COW mechanism.

> On Oct 12, 2016, at 1:11 PM, Károly Lőrentey  wrote:
> 
> I believe the implementation of efficient in-place mutation is very explicit 
> in the code -- it is done by implementing DictionaryValue’s subscript using a 
> special “mutableAddressWithNativeOwner” addressor instead of a normal setter. 
> 
> https://github.com/natecook1000/swift/blob/ed95aec4a20589a3b9c131f43444aa33705343cc/stdlib/public/core/HashedCollections.swift.gyb#L2169-L2173
>  
> <https://github.com/natecook1000/swift/blob/ed95aec4a20589a3b9c131f43444aa33705343cc/stdlib/public/core/HashedCollections.swift.gyb#L2169-L2173>
> 
> AFAICU this would also work if DictionaryValue was a reference type. 
> 
> Unfortunately, as far as I know, these addressors aren’t available outside 
> stdlib, so custom collections cannot currently implement such mutable views 
> (including mutable ranges) in a similarly efficient way. 
> 
> We can, however, approximate a similar effect outside of stdlib by designing 
> closure-based APIs like `mydict.withValues { values in values[i] = 42 }`, in 
> which the collection moves its storage to the view while the closure is 
> executing (temporarily making its own contents disappear / appear invalid). 
> The syntax and underlying mental model is perhaps not as nice, but (assuming 
> the compiler is able to optimize away the nonescaping closure) we can achieve 
> some of the performance benefits. 
> 
>> On 2016-10-12, at 19:17, plx via swift-evolution > <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Thanks for the quick reply; given that I’m quite wrong about the important 
>> mechanics I rescind my criticisms.
>> 
>> I will say I care about this enough to reply because the inability to do 
>> in-place mutation of dictionary values has been an incredibly frustrating 
>> limitation and I’d just assumed the situation with slices/views would 
>> necessarily have similar issues for similar reasons…but glad to learn it’s 
>> not what I thought!
>> 
>> That said, I think efficient in-place mutation is too important to only 
>> expose so implicitly (seemingly due to the compiler eliding the 
>> otherwise-expected retain increments when the view is sufficiently 
>> “transient”…which seems like you perhaps can’t have an "in-place capable" 
>> view that’s implemented as a class, I’d think).
>> 
>> But none of this impacts my change to being in support for the proposal.
>> 
>>> On Oct 12, 2016, at 10:07 AM, Nate Cook >> <mailto:natec...@gmail.com>> wrote:
>>> 
>>> 
>>>> On Oct 12, 2016, at 9:32 AM, plx via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> The issue addressed is real; I’m not 

Re: [swift-evolution] [Proposal] Refining Identifier and Operator Symbology

2016-10-19 Thread plx via swift-evolution
+💯 on the emoji-related parts, +1 in general spirit, +1 for the identifier 
cleanup, -103 for being needlessly overly-restrictive for operators; net -1 
overall.

Operator abuse is a social problem, and even if a technical fix is possible 
this isn’t that…and despite the messiness of the relevant unicode categories, 
this proposal goes far too far.

For operators, the reasonable thing to do at this time would be to hand-select 
a small subset of the mathematical characters to allow as operators—the 
“greatest hits” so to speak—and move on. If any grave oversights are discovered 
those characters can be included in subsequent major revisions; if the 
consortium ever finishes its recommendation it can be adopted at that time.

There’s no need to exhaustively re-do the consortium’s work and there’s no need 
to make a correct-for-all-time decision on each character at this time; pick 
the low-hanging fruit and leave the rest for later. 

That not everyone will be perfectly happy with any specific subset is 
predictable and not interesting; not everyone is going to be perfectly happy 
with this proposal’s proposed subset, either.

In any case, I’d specifically hate to lose these:

- approximate equality: ≈
- set operations: ∩, ∪ 
- set relations: ⊂, ⊃, ⊄, ⊅, ⊆, ⊇, ⊈, ⊉, ⊊, ⊋
- set membership: ∌, ∋, ∈, ∉
- logical operators: ¬, ∧, ∨

…although there are many more that would be nice to keep available. 

> On Oct 19, 2016, at 1:34 AM, Jacob Bandes-Storch via swift-evolution 
>  wrote:
> 
> Dear Swift-Evolution community,
> 
> A few of us have been preparing a proposal to refine the definitions of 
> identifiers & operators. This includes some changes to the permitted Unicode 
> characters.
> 
> The latest (perhaps final?) draft is available here:
> 
> 
> https://github.com/jtbandes/swift-evolution/blob/unicode-id-op/proposals/-refining-identifier-and-operator-symbology.md
>  
> 
> 
> We'd welcome your initial thoughts, and will probably submit a PR soon to the 
> swift-evolution repo for a formal review. Full text follows below.
> 
> —Jacob Bandes-Storch, Xiaodi Wu, Erica Sadun, Jonathan Shapiro
> 
> 
> Refining Identifier and Operator Symbology
> 
> Proposal: SE- 
> 
> Authors: Jacob Bandes-Storch , Erica Sadun 
> , Xiaodi Wu , Jonathan 
> Shapiro
> Review Manager: TBD
> Status: Awaiting review
>  
> Introduction
> 
> This proposal seeks to refine and rationalize Swift's identifier and operator 
> symbology. Specifically, this proposal:
> 
> adopts the Unicode recommendation for identifier characters, with some minor 
> exceptions;
> restricts the legal operator set to the current ASCII operator characters;
> changes where dots may appear in operators; and
> disallows Emoji from identifiers and operators.
>  
> Prior
>  discussion threads & proposals
> 
> Proposal: Normalize Unicode identifiers 
> 
> Unicode identifiers & operators 
> ,
>  with pre-proposal 
>  (a 
> precursor to this document)
> Lexical matters: identifiers and operators 
> 
> Proposal: Allow Single Dollar Sign as Valid Identifier 
> 
> Free the '$' Symbol! 
> 
> Request to add middle dot (U+00B7) as operator character? 
> 
>  
> Guiding
>  principles
> 
> Chris Lattner has written:
> 
> …our current operator space (particularly the unicode segments covered) is 
> not super well considered. It would be great for someone to take a more 
> systematic pass over them to rationalize things.
> We need a token to be unambiguously an operator or identifier - we can have 
> different rules for the leading and subsequent characters though.
> …any proposal that breaks:
> 
> let 🐶🐮 = "moof"
> will not be tolerated. :-) :-)
>  
> 

Re: [swift-evolution] [Proposal] Property behaviors

2015-12-18 Thread plx via swift-evolution
I am excited by the general direction but I have some concerns about the scope 
of the design at this time; specifically, it seems like it would benefit a lot 
from having some flexible-and-efficient way for behaviors to “reach upward” 
back into their container from within their custom methods (without forcing the 
caller to pass-in the container to each such call, of course).

I took a stab at mocking up one of the behaviors I’d like to be able to write 
and hit a lot of roadblocks due to the above; I’ve included it below with some 
commentary. 

Even though this is perhaps a rather extreme/niche behavior to want to 
implement, I think the issues it encountered are actually general enough that 
other useful behaviors will also encounter them under the proposal as sketched.

Here’s the sample use, starting with motivation.

For some APIs — e.g. CoreBluetooth — you often wind up with highly-stateful 
objects that receive callbacks on a specific queue, and typically also do their 
state-maintenance while on that same queue; these objects typically also have a 
“public API” with methods that are only meant for use while off the queue (e.g. 
from the main queue, to update the UI…).

You thus wind up with each method-and-property pretty clearly being one and 
only one of these:

- “on-queue”, e.g. *only* meant for use while on the object’s queue
- “off-queue”, e.g. *only* meant for use while off the object’s queue

…with concurrency-and-synchronization logic essentially amounting to only 
calling / using each method-and-property while appropriately on/off queue.

For a concrete example, for an implementer of CBCentralManagerDelegate:

- all the CBCentralManagerDelegate methods are "on-queue"
- all the BT-state-management methods (called in reaction to BT events) are 
also “on-queue”
- the public methods (e.g. for UI use, or for asking the object to do stuff) 
are “off-queue”
- some of the basic properties (status, is-peripheral-foo-connected?) are 
oddballs, and get:
  - private backing properties for use/update while on-queue
  - public off-queue accessors that do a dispatch_sync, read the backing 
property, and return it

…and so on.

This can all be handled today "by hand” — it just requires being careful — but 
it’d be nice to have a custom behavior that would streamline both the 
implementation of on/off queue access for properties, and make each site-of-use 
more self-documenting/self-verifying vis-a-vis on/off-queue status.

Here’s my best attempt (issues flagged in ALL-CAPS):

/// Object assumed to have private queue it uses for synchronization.
protocol PrivateQueueOwner : class {

  // we don’t want to leak the actual queue to the wider world,
  // so we have to bubble these up to the public API:
  func dispatchSync(@noescape action: () -> R) -> R
  func dispatchBarrierSync(@noescape action: () -> R) -> R
  func dispatchAsync(action: () -> ())
  func dispatchBarrierAsync(action: () -> ())

  // we assume we are managing our queues s.t. we can
  // actually get the below to work reliably:
  func isOnPrivateQueue() -> Bool

}

/// Behavior used to enforce a particular use-pattern around
/// a property of an object that uses a private queue for synchronization:
struct QueueAccess {
  var value: Value
  
  // THIS PART IS ONLY-KINDA OK:
  subscript(varIn container: Container> {
get {
  if container.isOnPrivateQueue() {
return self.value
  } else {
return self.container.dispatchSync() {
  return self.value
  // ^ DOES THIS ACTUALLY WORK AS I’D WANT, IF I AM A STRUCT?
}
  }
}
set {
  if container.isOnPrivateQueue() { 
self.value = newValue
  } else {
container.dispatchBarrierAsync() {
  self.value = newValue
  // ^ DOES THIS ACTUALLY WORK AS I’D WANT, IF I AM A STRUCT?
}
  }
}
  }

  // EVERYTHING FROM HERE ON DOWN IS MOSTLY PROBLEMATIC:

  func onQueueUpdate(newValue: Value) { 
assert(self.container.isOnPrivateQueue()) // <- HOW?
self.value = newValue
  }
  
  func offQueueUpdate(newValue: Value) {
assert(self.container.isOffPrivateQueue()) // <- HOW?
self.container.dispatchBarrierAsync() { // <- HOW?
   self.value = newValue
   // ^ DOES THIS EVEN WORK IF I AM A STRUCT?   
}
  }

  func offQueueAccess() -> Value {
assert(self.container.isOffPrivateQueue()) // <- HOW?
return self.container.dispatchSync() { // <- HOW?
  return self.value
}
  }

  func onQueueAcccess() -> Value {
assert(self.container.isOnPrivateQueue()) // <- HOW?
return self.value
  }

  func offQueueAccess(@noescape transform: (Value) -> R) -> R {
assert(self.container.isOffPrivateQueue()) // <- HOW?
return self.container.dispatchSync() { // <- HOW?
  return transform(self.value)
}
  }

  func onQueueAcccess(@noescape transform: (Value) -> R) -> R {
assert(self.container.isOnPrivateQueue()) // <- HOW?
return transform(self.value)
  }

}

….which

Re: [swift-evolution] [Review] Require self for accessing instance members

2015-12-18 Thread plx via swift-evolution
Quite quickly: 

I favor the proposal, but not for its stated reasons.

In isolation it’s not a big deal to have implicit-self or to not have 
implicit-self. It does offer real conveniences, albeit ones that are IMHO 
rather small-and-petty.

Given that, I think implicit self isn’t worth having if it gets in the way of 
higher-value features, and at least to my eyes that’s already happening.

Consider that both the "method-chaining" and the 
“introduce-new-scope-with-new-self” proposals have, to my read, stalled due to 
the apparent lack of any suitable syntax for them that’s:

- concise enough to be useful
- unambiguous enough to be implementable-and-usable
- in-line with / behaving-analogously-to the rest of the language

…with the concise syntax ideas being ambiguous largely due to issues either 
caused-by or made substantially-more-difficult due to implicit-self. 

I could be mischaracterizing the issues those proposals encountered — in which 
case I apologize — but even so, this kind of consideration is why I’d be in 
favor of dropping implicit-self; I suspect it either complicates or rules-out 
too many other useful things to really "pay it’s own way".

> On Dec 16, 2015, at 12:55 PM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of “Require self for accessing instance members” begins now and 
> runs through Sunday, December 20th. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0009-require-self-for-accessing-instance-members.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> 
>   Cheers,
>   Doug Gregor
>   Review Manager
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Epic: Typesafe calculations

2015-12-29 Thread plx via swift-evolution
FWIW I began a draft for a newtype/wrapper-synthesis proposal but abandoned it 
due to:

- (a) perceived lack of community interest 
- (b) running into *serious* complications around associated types

…note that this *didn’t* directly-address any sort of units system, but would 
be somewhat complementary (and a good first step in that direction). 

The short version of the issue in (b) is that whereas the desired 
behavior-and-semantics for “direct" newtype/wrapper-style constructs — where 
`Foo` is a newtype of `Bar` — seem pretty straightforward to specify, that’s 
not enough; you also have to deal with the “indirect” scenario, e.g. with 
situations in which `Foo` is a newtype of `Bar`, but `Bar` is also a 
`CollectionType`, and you want `Foo` to also be a `CollectionType` (or any 
other similar case).

In that specific case, you *probably* want this:

- `Foo.Element` == `Bar.Element`
- `Foo.Index` == a *newtype* of `Bar.Index` (e.g., not just a bare `Bar.Index`)
- `Foo.Generator` == `Bar.Generator` (I assume)
- `Foo.SubSequence` == 
  - `Foo`, when `Bar.SubSequence` == `Bar`
  - `Slice`, when `Bar.SubSequence` == `Slice`
  - a *newtype* of `Bar.SubSequence`, when `Bar.SubSequence` is some other type

…and although you can quibble with the exact choices here, the general issue is 
that it’s seemingly quite hard to really achieve the type-safety goals for some 
newtype/wrapper proposal without also addressing how to potentially “re-wrap” 
the wrapped type’s associated types.

It can be done I’m sure, but it’s seemingly rather involved; it definitely 
feels like a “Swift 4 (or later)” feature. If there’s enough community interest 
I could pick it up and flesh it out a bit more.

> On Dec 24, 2015, at 9:36 PM, Stephen Christopher via swift-evolution 
>  wrote:
> 
> I have been working for a couple weeks (since the previous [newtype 
> discussion](https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001821.html
>  
> )
>  ) on a related pitch. There seem to me to be multiple ways to solve this 
> problem - a newtype(esque) keyword, struct subtyping, or forwarding as 
> Matthew is suggesting. I’d hoped to have a discussion starter out before the 
> holidays, but it takes a fair amount of work to put together even a decent 
> draft for a proposal. This is top of my list currently for a way to 
> contribute though. Looking forward to the ensuing discussions.
> 
> Thanks for the pointer on class delegation. I’ve looked at delegated 
> properties there (which came up in relation to Joe’s recent proposal for 
> behaviors on properties).
> 
> - Step Christopher
> 
> 
> 
> On Thu, Dec 24, 2015 at 2:40 PM, Matthew Johnson via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
> 
> Sent from my iPad
> 
> > On Dec 24, 2015, at 1:07 PM, Tino Heth <2...@gmx.de > 
> > wrote:
> >
> >
> >> I'm planning to write a proposal for automatic forwarding.
> > Something like class delegation in Kotlin?
> > Please hurry, I've no work to distract me for the rest of the year, and 
> > extending typealias could be a very quick proposal ;-)
> 
> Details are still brewing.  I am not familiar with class delegation in Kotlin 
> but will look it up.  Thanks for mentioning it!
> 
> I plan to spend a lot of time on Swift proposal work over the next week and a 
> half but can't make any promises on timing.  I made that mistake with my 
> proposal on flexible memberwise initialization which ended up taking a couple 
> weeks longer than I expected (for several reasons).  What I can say is that 
> this is pretty high on my Swift proposal priority list.
> 
> Matthew
> ___
> 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] Proposal: CollectionType.cycle property for an infinite sequence

2015-12-29 Thread plx via swift-evolution
Personally I’d say this should be a -1 for standard-library inclusion.

Swift’s not really built to handle infinite sequences right now; until they are 
handed better by the standard library convenience methods for creating them 
shouldn’t be in the standard library.

You’d also want to call `fatalError` for at least `reduce`, `reverse`, `sort`, 
`split`(?), `flatMap`, `dropLast`, `suffix`, and `forEach`.

`startsWith` and `elementsEqual` and `lexicographicComparison` are all broken 
if you call them like e.g. `self.startsWith(self)`.

You can conceivably implement a non-crashing `contains`, `minElement` and 
`maxElement` on `CycleSequence` by calling through to the wrapped collection, 
but that’ll seemingly evaporate as soon as your `CycleSequence` winds up hidden 
inside an `AnySequence`.

Which illustrates why this is a -1 for me; there's nothing wrong with the 
functionality in isolation and there’s nothing wrong with infinite sequences, 
but the standard library should play well with itself, and this wouldn’t play 
well with the rest of the standard library.

That opinion could change as the language changes or the standard library 
evolves.

> On Dec 28, 2015, at 1:20 AM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> ## Introduction
> 
> Add a new property `cycle` to CollectionType that returns an infinite 
> SequenceType that yields the elements of the collection in a loop.
> 
> ## Motivation
> 
> It's sometimes useful to be able to have an infinite sequence. For example, 
> `CollectionOfOne(x).cycle` could be used to have an infinite sequence of a 
> single element (similar to Repeat but without a count). A common use for 
> infinite sequences is zipping with a finite sequence. As far as I'm aware, 
> the stdlib does not currently provide any way to create such an infinite 
> sequence.
> 
> ## Proposed solution
> 
> Extend CollectionType with a new property `cycle` that yields a type that 
> conforms to SequenceType. This sequence yields each element of the collection 
> in an infinite loop.
> 
> ## Detailed design
> 
> 2 new types would be added:
> 
> struct CycleSequence : LazySequenceType { ... }
> struct CycleGenerator : GeneratorType { ... }
> 
> CollectionType would be extended with a property:
> 
> extension CollectionType {
>public var cycle: CycleSequence { get }
> }
> 
> This is an extension of CollectionType instead of SequenceType because it 
> requires a multi-pass sequence (and SequenceType does not provide that 
> guarantee). The returned type conforms to SequenceType instead of 
> CollectionType because there is no possible `endIndex` that satisfies the 
> requirement of being reachable from `startIndex` by zero or more applications 
> of `successor()`.
> 
> Because the default eager versions of map and filter will execute forever on 
> an infinite sequence, CycleSequence conforms to LazySequenceType instead of 
> SequenceType in order to provide lazy versions of those functions. 
> Additionally, it will provide implementations of the eager versions that 
> simply trigger a fatalError(), as the alternative is an infinite loop that 
> consumes more and more memory.
> 
> ## Impact on existing code
> 
> None
> 
> -Kevin Ballard
> ___
> 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] Proposal: CollectionType.cycle property for an infinite sequence

2015-12-29 Thread plx via swift-evolution

> On Dec 29, 2015, at 1:17 PM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> On Tue, Dec 29, 2015, at 08:14 AM, plx via swift-evolution wrote:
>> Personally I’d say this should be a -1 for standard-library inclusion.
>> 
>> Swift’s not really built to handle infinite sequences right now; until they 
>> are handed better by the standard library convenience methods for creating 
>> them shouldn’t be in the standard library.
> 
> As far as I can tell, the only way in which it's "not really built" to handle 
> this is that there are multiple constructs that attempt to eagerly consume an 
> entire sequence, and using these with an infinite sequence would end up 
> looping forever. But I don't consider that to be a particularly serious 
> problem. You could "fix" it by refactoring SequenceType into two protocols, 
> SequenceType (for possibly-infinite sequences) and FiniteSequenceType (for 
> known-finite sequences) and then going over the entire standard library and 
> updating various spots to use FiniteSequenceType, except this would be very 
> limiting (sequences that are not known if they're infinite to the compiler 
> could still be valid for various eager algorithms if the programmer knows it 
> will be finite in practice).

Indeed, on my wishlist I would like to see the standard protocols refactored to 
something more like this:

SequenceType // can be iterated
FiniteSequenceType : SequenceType, // of finite length
StableSequenceType : SequenceType, // can be re-iterated identically
CollectionType : StableSequenceType, FiniteSequenceType, (etc.) // otherwise as 
it is now

…but can understand the wish to not overly-complicate the basic protocol 
hierarchy (and also to avoid baking-in nice-to-have, but 
impossible-to-really-enforce semantic requirements; I’d trust the standard 
library to use them properly, but not typical 3rd party code, somewhat 
defeating the purpose).

Everything else is a difference of outlook; we agree on the facts and differ in 
interpretation.

I consider concrete types that adopt a protocol only to simply call 
`fatalError` for most of the protocol methods to be pathological — often 
useful, but still pathological — and thus far the standard library doesn’t 
contain any such pathological types (to my knowledge).

`cycle` is useful but not useful enough to be the standard library’s first 
“pathological” type, so it’s still a -1 as proposed.

This is nothing specific to `cycle` and my opinion here could change were the 
language or the standard library to evolve in various ways.
> 
>> You’d also want to call `fatalError` for at least `reduce`, `reverse`, 
>> `sort`, `split`(?), `flatMap`, `dropLast`, `suffix`, and `forEach`.
> 
> You can only do it for the ones defined in the protocol, not ones defined in 
> extensions. This means map, filter, forEach, and suffix.
> 
> split is actually perfectly implementable for a CycleSequence, although it 
> does need a custom implementation. split is bounded by at most Int.max 
> splits, which means it is guaranteed to terminate even for an infinite 
> sequence (although the final subsequence does need to be infinite[1]). Even 
> if there are no separators in the cycle, it can just return the cycle itself.
> 
> [1] Interestingly, the current implementation actually dumps the remainder 
> into an Array and returns that (wrapped in AnySequence), which is curious 
> because it would be perfectly legal for it to just wrap the generator up in 
> AnySequence and return that instead. I'm tempted to submit a PR to change 
> that now, as it just seems like unnecessary work to use an array.
> 
>> `startsWith` and `elementsEqual` and `lexicographicComparison` are all 
>> broken if you call them like e.g. `self.startsWith(self)`.
> 
> That's true, but what do you really expect when you're calling them with two 
> infinite sequences? It's not so much that they're broken as it is that you're 
> creating an infinite loop without any way to break out. And FWIW, 
> lexicographicalCompare is actually something you might want to explicitly 
> support on infinite sequences if you know your sequences aren't equal and 
> want to find out which one is less than the other.
> 
> There are plenty of ways to shoot yourself in the foot. I don't think 
> infinite sequences are really the big problem you're making them out to be.
> 
>> You can conceivably implement a non-crashing `contains`, `minElement` and 
>> `maxElement` on `CycleSequence` by calling through to the wrapped 
>> collection, but that’ll seemingly evaporate as soon as your `CycleSequence` 
>> winds up hidden inside an `AnySequence`.
> 
> You can't override those anyway in a generic context, because t

Re: [swift-evolution] [Proposal Draft] automatic protocol forwarding

2015-12-30 Thread plx via swift-evolution
Thanks for writing this up.

Some quick points.

Firstly, I think it is best if the `init(_ forwardeeReturnValue: 
Forwardee)`-style initializer be replaced by something with a distinctly-named 
argument, e.g. `init(forwardeeReturnValue value: Forwardee)`. 

For use with actual wrapper types the “init(_ wrappedValue: Wrapped)`-style 
init is too valuable to “claim” for this purpose (in particular b/c we may want 
to “adjust" the forwarded result); it’s IMHO better if we use a distinct `init` 
for the forwardee-return-value scenario so we know where the value is coming 
from.

Secondly, I would prefer partial-forwarding be given more consideration, b/c it 
seems somewhat common for me in practice at this time.

EG: I would do the following somewhat frequently:

struct FooIdentifier: Equatable, Comparable, Hashable

class Foo {
  let identifier: FooIdentifier
  let name: String

  forward Hashable to identifier
}

func ==(lhs: Foo, rhs: Foo) -> Bool {
  return lhs.identifier == rhs.identifier && lhs.name == rhs.name
}

…even though I agree that full-forwarding would the most-common scenario.

I have a few other similar cases involving non-standard-library types but they 
all fit the same basic pattern as above for `Hashable`.

Finally, I’m actually at a bit of a loss for too many uses for the generic 
forwarding mechanism; if it was added I’d use it to streamline some wrapper 
types, but beyond that I’m not seeing all that many places where I’d do much 
more than that with this feature if added.

Any chance at adding a few more-concrete motivating examples for the fancier 
cases?

> On Dec 29, 2015, at 10:37 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> I have completed a first draft of a proposal to introduce automatic protocol 
> forwarding.  I’m looking forward to feedback from everyone!

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


Re: [swift-evolution] Proposal: CollectionType.cycle property for an infinite sequence

2015-12-30 Thread plx via swift-evolution

> On Dec 29, 2015, at 6:38 PM, Dave Abrahams  wrote:
> 
> 
>> On Dec 29, 2015, at 3:39 PM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Dec 29, 2015, at 1:17 PM, Kevin Ballard via swift-evolution 
>>> mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> On Tue, Dec 29, 2015, at 08:14 AM, plx via swift-evolution wrote:
>>>> Personally I’d say this should be a -1 for standard-library inclusion.
>>>> 
>>>> Swift’s not really built to handle infinite sequences right now; until 
>>>> they are handed better by the standard library convenience methods for 
>>>> creating them shouldn’t be in the standard library.
>>> 
>>> As far as I can tell, the only way in which it's "not really built" to 
>>> handle this is that there are multiple constructs that attempt to eagerly 
>>> consume an entire sequence, and using these with an infinite sequence would 
>>> end up looping forever. But I don't consider that to be a particularly 
>>> serious problem. You could "fix" it by refactoring SequenceType into two 
>>> protocols, SequenceType (for possibly-infinite sequences) and 
>>> FiniteSequenceType (for known-finite sequences) and then going over the 
>>> entire standard library and updating various spots to use 
>>> FiniteSequenceType, except this would be very limiting (sequences that are 
>>> not known if they're infinite to the compiler could still be valid for 
>>> various eager algorithms if the programmer knows it will be finite in 
>>> practice).
>> 
>> Indeed, on my wishlist I would like to see the standard protocols refactored 
>> to something more like this:
>> 
>> SequenceType // can be iterated
>> FiniteSequenceType : SequenceType, // of finite length
>> StableSequenceType : SequenceType, // can be re-iterated identically
>> CollectionType : StableSequenceType, FiniteSequenceType, (etc.) // otherwise 
>> as it is now
> 
> This is interesting. A few concerns:
> 
> First, we have tried not to create any distinct protocols with identical 
> syntactic requirements, because we think it makes the world clearer; we think 
> people are more likely to assign incorrect protocols when all the operations 
> they want are available, but don’t have the right semantics.  That isn’t to 
> say we shouldn’t start doing it, but it would be a break from the past.
> 
> Higher protocol granularity has a high comprehensibility cost.  
> Distinguishing protocols based on semantic requirements alone may make the 
> library harder to understand.  I’ve heard some people’s heads have exploded 
> from simply encountering CollectionType. 
> 
> Next, it’s a principle of generic programming that every protocol should be 
> justified by both algorithms that exploit its requirements (e.g. extension 
> methods) and some real-world models that can’t reasonably also conform to a 
> more-refined protocol.  For example, we have a ForwardIndexType because a 
> singly-linked list has multipass forward traversal and can’t do bidirectional 
> traversal.  In order to evaluate any proposal for new protocols, we’d need to 
> see all of these things.

Speaking frankly, I’d say that there are few benefits to a refactoring along 
the lines sketched above until/unless you want to have solid support for things 
like a product-sequence or product-collection; you would gain *significant* 
advantages from such a refactored hierarchy in such scenarios, but I can’t 
think of any meaningful improvement the refactoring would offer in the 
essentially-linear case. (Note that this is distinct from examples of concrete 
models that are naturally e.g. finite-but-not-stable and vice-versa; they 
exist, but the rest is already long enough as it is).

A full example is beyond my time-budget here, but I can give the flavor of 
where it makes a difference somewhat quickly.

Consider a hypothetical `ProductSequence2` that 
enumerates the cartesian product of two sequences (in an unspecified order); 
the naive implementation has problems with non-stable sequences and with 
infinite-sequences, but I’ll only discuss the infinite case b/c it’s more 
relevant here.

When either—or both—of the sequences are infinite, the order-of-iteration has 
actual observable consequences; as a concrete example, if you want this to work 
out:

ProductSequence2([1,2].cycle,[1,2].cycle).contains((2,2)) == true

…then we have this:

- if `a` is finite and `b` is not, you want to iterate like (a0,b0), (a1,b0), 
(a2, b0) … , (a0, b1), (a1, b1), …, etc
- if `b` is finite and `a` is not, you want to iterate like (a0,b0), (a0,b1), 
(a0, b2) … , (a1

Re: [swift-evolution] [Proposal Draft] automatic protocol forwarding

2015-12-30 Thread plx via swift-evolution

> On Dec 30, 2015, at 10:27 AM, Matthew Johnson  wrote:
> 
> 
>> On Dec 30, 2015, at 10:06 AM, plx via swift-evolution 
>>  wrote:
>> 
>> Thanks for writing this up.
> 
> Thanks for responding with comments.
> 
>> 
>> Some quick points.
>> 
>> Firstly, I think it is best if the `init(_ forwardeeReturnValue: 
>> Forwardee)`-style initializer be replaced by something with a 
>> distinctly-named argument, e.g. `init(forwardeeReturnValue value: 
>> Forwardee)`. 
>> 
>> For use with actual wrapper types the “init(_ wrappedValue: Wrapped)`-style 
>> init is too valuable to “claim” for this purpose (in particular b/c we may 
>> want to “adjust" the forwarded result); it’s IMHO better if we use a 
>> distinct `init` for the forwardee-return-value scenario so we know where the 
>> value is coming from.
> 
> Did you look at the approach Brent suggested yesterday?  I’m going to update 
> the proposal using something similar to that.  We won’t be claiming any init 
> at all.  It will be slightly less concise in the common case but will add 
> clarity, expressiveness, and resolve problems related to forwarding to more 
> than one member of the same type.

I did not but will make sure to read it.

> 
>> 
>> Secondly, I would prefer partial-forwarding be given more consideration, b/c 
>> it seems somewhat common for me in practice at this time.
> 
> If somebody from the core team was enthusiastic about including partial 
> forwarding in the initial proposal rather than as an enhancement that would 
> certainly motivate me to reconsider.
> 
> As I stated earlier and in the proposal, one reason I left it out is that 
> partial forwarding introduces similar concerns that arise with subclassing.  
> Should a protocol or a type designed to be a forwardee be able to include 
> annotations indicating that some members cannot be “overriden” by a 
> forwarder?  I haven’t had time to fully consider whether that is a good idea 
> or not and if it is, what it would look like, how it should work, etc.  I am 
> reluctant to introduce partial forwarding without really thinking this 
> through.
> 
>> 
>> EG: I would do the following somewhat frequently:
>> 
>> struct FooIdentifier: Equatable, Comparable, Hashable
>> 
>> class Foo {
>> let identifier: FooIdentifier
>> let name: String
>> 
>> forward Hashable to identifier
>> }
>> 
>> func ==(lhs: Foo, rhs: Foo) -> Bool {
>> return lhs.identifier == rhs.identifier && lhs.name == rhs.name
>> }
>> 
> 
> Thanks for providing an example!  It looks like you would have two different 
> instances representing the same entity, possibly one serving as an edit 
> buffer.  Is that why they might have the same identifier but different names? 
>  

This is suffering from the “short examples will necessarily feel contrived, 
long examples are too long to be polite” problem. Sometimes it’s just from 
laziness — a good composite `hashValue` can be hard to write, so why not stick 
with a known-good `hashValue` implementation? — and often makes sense in 
context (if you know that same-ID, logically-different objects will be rare 
enough to have negligible overall impact).

I totally agree though I’m getting essentially nothing from forwarding here.

Similar scenarios can show up somewhat *artificially* in the context of generic 
code. Here’s a somewhat-contrived example:

Suppose you want to write a generic function that can look an “old” array and a 
“new” array and infer an “edit sequence” that can be applied to transform the 
“old” one into the “new” one, with an added complication: some values in the 
“new” one are *revisions* of values from the old one (and thus !=, but still 
“representing the same thing”). 

This could be implemented a lot of different ways; one of them might look like 
this: 

protocol RecordIdentifierType : Equatable, Comparable, Hashable {} // 
etc
protocol IdentifiableRecordType : Equatable, Hashable {
  typealias Identifier: RecordIdentifierType
  typealias Data: Equatable // weakest guarantee we need for what we 
plan to use this for
  // deliberately-clunky names to avoid accidental collisions:  
  var recordIdentifier: Identifier { get }
  var recordData: Data { get }
}

func inferredEditOperations(
  forPreviousRecords previousRecords: [R],
  currentRecords: [R]) -> ArrayEditOperation {
  // exercise for reader
}

…wherein 99% of the time a typical concrete conformance would just return 
`self` as `recordData` and some appropriate property as `recordIdentifier`, but 
it’d still be handy to have an “adaptor" type laying around like this:

Re: [swift-evolution] [Proposal draft] Generalized Naming for Any Function

2015-12-30 Thread plx via swift-evolution
I like this proposal overall and the proposed syntax in particular; I think it 
addresses a real issue in a straightforward, predictable way.

As an aside — and FWIW — one thing I was at some point going to propose was a 
shorthand syntax for specifying trivial “argument-ordering-adjustment” closures.

EG: in the context of the proposal, a shorthand like this:

let indicesForViews: [(Int,UIView)] = …
indicesForViews.forEach(self.`insertSubview($1,at:$0)`)

…although using something other than back-ticks may be necessary to avoid 
ambiguity.

In the example above, it’s a bit contrived; in general, it’s never 
actually-shorter than the current option:

let indicesForViews: [(Int,UIView)] = …
indicesForViews.forEach({ self.insertSubview($1, at: $0) })

…but it would still make things more symmetric between the “function name” case 
and the inline-short-closure case.

More importantly, it’d allow a streamlined way to express things like this:

// shorthand:
let flippedArguments = self.`insertSubview($1, at: $0)` 

// current syntax:
let flippedArguments = { (Int,UIView) -> Void in self.insertSubview($1, 
at: $0) }

…which will be a lot more useful once we have a reliable way to pull such 
functions into local variables.

I’m not requesting this be included in the below proposal, just hoping the 
final syntax selected here not somehow inadvertently prevent such a construct 
from ever being created.

Apologies if this has already come up in the discussion.

> On Dec 27, 2015, at 1:22 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hi all,
> 
> Here’s a proposal draft to allow one to name any function in Swift. In 
> effect, it’s continuing the discussion of retrieving getters and setters as 
> functions started by Michael Henson here:
> 
>   
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/002168.html
>  
> 
> 
> the proposal follows, and is available here as well:
> 
>   
> https://github.com/DougGregor/swift-evolution/blob/generalized-naming/proposals/-generalized-naming.md
>  
> 
> 
> Comments appreciated!
> 
> Generalized Naming for Any Function
> 
> Proposal: SE- 
> 
> Author(s): Doug Gregor 
> Status: Awaiting Review
> Review manager: TBD
>  
> Introduction
> 
> Swift includes support for first-class functions, such that any function (or 
> method) can be placed into a value of function type. However, it is not 
> possible to specifically name every function that is part of a Swift 
> program---one cannot provide the argument labels when naming a function, nor 
> are property and subscript getters and setters referenceable. This proposal 
> introduces a general syntax that allows one to name anything that is a 
> function within Swift in an extensible manner.
> 
> Swift-evolution thread: Michael Henson started a thread about the 
> getter/setter issue here 
> ,
>  continued here 
> .
>  See the Alternatives considered 
> 
>  section for commentary on that discussion.
> 
>  
> Motivation
> 
> It's fairly common in Swift for multiple functions or methods to have the 
> same "base name", but be distinguished by parameter labels. For example, 
> UIView has three methods with the same base name insertSubview:
> 
> extension UIView {
>   func insertSubview(view: UIView, at index: Int)
>   func insertSubview(view: UIView, aboveSubview siblingSubview: UIView)
>   func insertSubview(view: UIView, belowSubview siblingSubview: UIView)
> }
> When calling these methods, the argument labels distinguish the different 
> methods, e.g.,
> 
> someView.insertSubview(view, at: 3)
> someView.insertSubview(view, aboveSubview: otherView)
> someView.insertSubview(view, belowSubview: otherView)
> However, when referencing the function to create a function value, one cannot 
> provide the labels:
> 
> let fn = someView.insertSubview // ambiguous: could be any of the three 
> methods
> In some cases, it is possible to use type annotations to disambiguate:
> 
> let fn: (UIView, Int) = someView.insertSubview// ok: uses 
> insertSubview(_:at:)
> let fn: (UIView, UIView) = someView.ins

Re: [swift-evolution] Proposal: CollectionType.cycle property for an infinite sequence

2015-12-30 Thread plx via swift-evolution

> On Dec 30, 2015, at 3:39 PM, Kevin Ballard via swift-evolution 
>  wrote:
> 
> Refactoring like that can always be done later; introducing infinite 
> sequences now shouldn't make it any harder to refactor the protocols. If 
> anything, it will provide more practical experience with how infinite 
> sequences interact with the current protocol hierarchy that would help guide 
> the design of any refactoring (or, perhaps more importantly, help determine 
> if such a refactoring is worthwhile).
>  
> A big concern I have with refactoring like that is you'd rarely ever be able 
> to actually bound an algorithm on FiniteSequenceType, because there will 
> always be ways of constructing sequences that the compiler can't tell if it's 
> infinite. Trivial example is `ary.cycle.takeWhile(pred)`. This is infinite if 
> `pred(elt)` is true for every element of `ary` and finite otherwise. But 
> there's tons of other ways of creating such indeterminate sequences. Bounding 
> algorithms (such as `map(..) -> [T]` or `reduce()`) on finite sequences only 
> would be rather limiting, as users who know their sequence must be finite but 
> can't prove it to the compiler would be unable to use methods that are in 
> fact perfectly safe.

If you will accept that I would prefer the standard library types to interpret 
the standard library protocols as having already made such a binding — as, 
indeed, the type signatures necessarily imply — the rest of my objection should 
be comprehensible.

I don’t find the repeated points about what can happen due to user error to be 
interesting.

> 
> What you could do with such a refactoring is optimize certain algorithms if 
> they use a more precise sequence type, but I'm not actually sure what sort of 
> optimizations you can make with your proposed protocol hierarchy. In fact, 
> the only real optimizations that come to mind are optimizing when you know 
> you're working with a CycleSequence, because for various algorithms you 
> really only have to iterate the underlying elements once (e.g. assuming a 
> pure predicate, CycleSequence can implement contains() safely, although we 
> don't actually have pure in the language right now so that's not necessarily 
> a safe assumption; also, contains() isn't a protocol method, just an 
> extension method, so we can't actually do that anyway).

I already gave the example of a product sequence. There’s a simple 
implementation that is correct when both input sequences are finite-and-stable, 
but not necessarily if otherwise; the proposed refactoring would statically 
provides enough information to allow one to choose the minimally-*pessimal* 
implementation that is still correct for such inputs. 

How much correctness matters is, of course, essentially subjective.

>  
> On that note, core language team, anyone know offhand why SequenceType has a 
> bunch of extension methods that aren't part of the protocol? For example, 
> contains(_ predicate:). The only real reason I can think of is to shrink the 
> protocol witness table, but surely that's not particularly meaningful. I 
> warrant that contains(_ predicate:) doesn't really have any reason to be 
> overridden by anything except sequences that knowingly repeat elements (e.g. 
> CycleSequence and Repeat), and even that's only if you assume the predicate 
> is pure, but there's some other methods that make sense to override on some 
> sequences (like minElement(_ isOrderedBefore:) for any sequence that has a 
> defined ordering).

I am not sure how, precisely, you would propose to override the closure-taking 
variant of `minElement` to take advantage of an intrinsic ordering, but I’d be 
curious to see it.

I’d hope that the non-closure-accepting variants would be made overridable once 
the type system supports it.

>  
> -Kevin Ballard
>  
> On Wed, Dec 30, 2015, at 11:01 AM, plx via swift-evolution wrote:
>>  
>>> On Dec 29, 2015, at 6:38 PM, Dave Abrahams >> <mailto:dabrah...@apple.com>> wrote:
>>>  
>>>  
>>>> On Dec 29, 2015, at 3:39 PM, plx via swift-evolution 
>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>  
>>>>>  
>>>>> On Dec 29, 2015, at 1:17 PM, Kevin Ballard via swift-evolution 
>>>>> mailto:swift-evolution@swift.org>> wrote:
>>>>>  
>>>>> On Tue, Dec 29, 2015, at 08:14 AM, plx via swift-evolution wrote:
>>>>>> Personally I’d say this should be a -1 for standard-library inclusion.
>>>>>>  
>>>>>> Swift’s not really built to handle infinite sequences right now; until 
>>>>>> they are handed better by the stan

[swift-evolution] Inquiry: Status of SR-122 ?

2016-01-01 Thread plx via swift-evolution
I was preparing a proposal-sketch relating to this earlier discussion: 
http://article.gmane.org/gmane.comp.lang.swift.evolution/1629

…which is largely about inserting "intermediate steps” between `SequenceType` 
and `CollectionType`, but to get the full benefit would likely wind up 
requiring modifications to the API on the `*Index` types (e.g. 
`ForwardIndexType`, which at present is required of a `CollectionType`’s 
`Index`).

Searching for prior discussion/work I found this bug: 
https://bugs.swift.org/browse/SR-122 , and was curious if anything further has 
happened on that topic?


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


Re: [swift-evolution] [Review] Replace `typealias` keyword with `associatedtype` for associated type declarations

2016-01-03 Thread plx via swift-evolution
I like this.

> On Jan 3, 2016, at 1:38 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "Replace `typealias` keyword with `associatedtype` for 
> associated type declarations” begins now and runs through Wednesday, January 
> 6th. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   * What is your evaluation of the proposal?

It’s a good idea and improves the language.

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

Yes, the existing situation is comprehensible (if you think like a 
language-implementer) but highly non-intuitive and generally sub-optimal for 
language users.

>   * Does this proposal fit well with the feel and direction of Swift?

Yes; conservation-of-reserved-terms is valuable, but giving different things 
different names fits the feel much better here.

>   * If you have you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?

To the extent I’m aware of analogous situations in other languages, none of 
them actually seem to use distinct keywords, but they also don’t have the 
confusing situation Swift has vis-a-vis typealiases with concrete definitions 
(in protocols).

>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

Quick read, plus having been bit by issues the proposal addresses numerous 
times.

> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> 
>   Cheers,
>   Doug Gregor
>   Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Inquiry: Status of SR-122 ?

2016-01-03 Thread plx via swift-evolution
Thanks for pointing me at it; at a quick read I like the functionality, but 
will have to take a closer look to get a sense of its feel in use.

It certainly addresses the current gripes I have around `CollectionType` 
requiring a `ForwardIndexType`: for all but the truly-linear collections (e.g., 
Array-like) implementing `successor()` either forces you to hold a 
back-reference, or leaves you choosing between holding a back-reference or 
having rather “fat” indices.

If the collection becomes responsible for moving the index this is all mooted; 
I can finish the sketched refactoring proposal and simply refer to this 
(prototype? proposal?) as something else that’d be needed to get the full 
benefit.

> On Jan 2, 2016, at 11:24 AM, Dmitri Gribenko  wrote:
> 
> On Sat, Jan 2, 2016 at 4:53 AM, Dave Abrahams via swift-evolution
>  wrote:
>> 
>>> On Jan 1, 2016, at 4:34 PM, plx via swift-evolution 
>>>  wrote:
>>> 
>>> I was preparing a proposal-sketch relating to this earlier discussion: 
>>> http://article.gmane.org/gmane.comp.lang.swift.evolution/1629
>>> 
>>> …which is largely about inserting "intermediate steps” between 
>>> `SequenceType` and `CollectionType`, but to get the full benefit would 
>>> likely wind up requiring modifications to the API on the `*Index` types 
>>> (e.g. `ForwardIndexType`, which at present is required of a 
>>> `CollectionType`’s `Index`).
>>> 
>>> Searching for prior discussion/work I found this bug: 
>>> https://bugs.swift.org/browse/SR-122 , and was curious if anything further 
>>> has happened on that topic?
>> 
>> Yes, Dmitri has been making progress on an implementation.  He may be able 
>> to point you at it…
> 
> The prototype is checked in at
> test/Prototypes/CollectionsMoveIndices.swift, feel free to ask me more
> questions about it.
> 
> Dmitri
> 
> -- 
> main(i,j){for(i=2;;i++){for(j=2;j (j){printf("%d\n",i);}}} /*Dmitri Gribenko */

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


Re: [swift-evolution] [Review] Replace `typealias` keyword with `associatedtype` for associated type declarations

2016-01-04 Thread plx via swift-evolution
On a re-read I am -1; I like the `associatedtype` keyword but didn’t realize 
there was no plan to let `typealias` be used within a protocol to as a 
convenience (and to preserve intent, and to improve the development experience 
when still figuring out an interface design).

I would prefer the new keyword and also adding/allowing one to add convenience 
typealiases within a protocol definition.

I have not followed the discussion closely to know if there are difficult 
technical issues with permitting both `associatedtype` declarations and simple 
convenience `typealias` declarations within a protocol, or if the current 
proposal is simply making the possible-confusion argument; if there are legit 
technical issues then so be it, but if it’s just an 
argument-from-possible-confusion I think the price of clarity is dearer than it 
needs to be here.

> On Jan 3, 2016, at 1:38 AM, Douglas Gregor via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The review of "Replace `typealias` keyword with `associatedtype` for 
> associated type declarations” begins now and runs through Wednesday, January 
> 6th. The proposal is available here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0011-replace-typealias-associated.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager.
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   * What is your evaluation of the proposal?
>   * Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   * Does this proposal fit well with the feel and direction of Swift?
>   * If you have you used other languages or libraries with a similar 
> feature, how do you feel that this proposal compares to those?
>   * How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
>   https://github.com/apple/swift-evolution/blob/master/process.md 
> 
> 
>   Cheers,
>   Doug Gregor
>   Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Review] Replace `typealias` keyword with `associatedtype` for associated type declarations

2016-01-04 Thread plx via swift-evolution
And of course it’s not like this is taking away functionality, just not adding 
it yet. So sure, +1, this is still forward progress. 

The fact it’s so easy to forget this other use of typealias doesn't really work 
in protocols right now is evidence enough for the proposal. Apologies for the 
double-about face.

> On Jan 4, 2016, at 6:17 PM, Brent Royal-Gordon  wrote:
> 
>> On a re-read I am -1; I like the `associatedtype` keyword but didn’t realize 
>> there was no plan to let `typealias` be used within a protocol to as a 
>> convenience (and to preserve intent, and to improve the development 
>> experience when still figuring out an interface design).
>> 
>> I would prefer the new keyword and also adding/allowing one to add 
>> convenience typealiases within a protocol definition.
> 
> I would love to see convenience typealiases supported in protocols 
> eventually, but I actually think that should wait until after the transition 
> to `associatedtype` is well behind us so we can get people used to the new 
> keyword.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] About the PermutationGenerator

2016-01-06 Thread plx via swift-evolution

> On Jan 6, 2016, at 11:37 AM, Jordan Rose via swift-evolution 
>  wrote:
> 
> I've bounced this idea off of Dave and Dmitri internally, so might as well 
> put it out publicly:
> 
> In Magic DWIM Swift, there would only be two types that you'd ever conform 
> to: a destructive iteration type (today's "Generator"), and a multi-pass 
> indexed type (today's "Collection"). Some operations can meaningfully use 
> either one (like forEach or maxElement); these operations go on a general 
> "traversable" type (today's "Sequence").
> 
> In this world, both GeneratorType and CollectionType are refinements of 
> SequenceType (i.e. any GeneratorType "is-a" SequenceType), including the 
> necessary default implementations. Maybe we rename some of the protocols in 
> the process. Again, no concrete type would ever conform to SequenceType; it's 
> just something you can use as a generic constraint.
> 
> We can't actually do this today because it creates a circularity between 
> SequenceType and GeneratorType that the compiler can't handle. I'm pretty 
> sure it's possible to change the compiler's protocol checking logic to allow 
> this, though.
> 
> Anyway, that's that idea. At the very least it helped me clear up my thoughts 
> about Sequence, Collection, and Generator back when I was first learning them.
> 
> Jordan
> 
> P.S. This idea falls apart if someone comes up with a model (concrete type) 
> for SequenceType that isn't a Collection or Generator. I wasn't able to think 
> of one back when I was originally thinking about this, but of course that 
> doesn't mean there isn't one. (Infinite collections are interesting as 
> discussed on the "cycle" thread, but it's not the sequence/generator 
> distinction that's really meaningful there.)

It’s not clear what you mean by a `SequenceType` that isn’t either a 
`Collection` or a `Generator`, but if you mean a *concrete* sequence that:

- can be re-iterated (thus not a `Generator`)
- has no meaningful index (!) (thus not a `Collection`)

…then I can provide you with examples of such. The (!) is b/c you can of course 
always use `Int` as an index, in the sense that “the value at index `n` is 
obtained by iterating `n` steps from the start of the sequence”; I’ll assume 
this doesn’t “count” as an index for purposes of this discussion.

Given the above, I will provide two examples.

Here is one that is stable, re-iterable, infinite, and has no “non-trivial" 
index:

// Modest generalization of a seedable PRNG.
// We assume that identically-seeded sources generate
// identical elements (via `randomElement`), in identical order.
protocol RandomElementSourceType {

  typealias Element
  typealias Seed: Equatable
  // ^ `:Equatable` isn't actually necessary, but it's nice
  
  init(seed: Seed)
  
  mutating func randomElement() -> Element

}

struct RandomElementGenerator : GeneratorType {

  typealias Element = R.Element
  
  private var source: R
  
  mutating func next() -> Element? {
return source.randomElement() // <- never stops!
  }
  
}

struct RandomElementSequence : SequenceType {

  typealias Generator = RandomElementGenerator
  
  private let seed: R.Seed
  
  func generate() -> Generator {
return Generator(source: R(seed: seed))
// ^ as per assumptions, each iteration will be identical b/c
//   because each iteration uses the same seed 
  }

}

…and here is one that is not-necessarily-stable, reiteration-capable, finite 
(one hopes!), and with no “non-trivial” index:

struct SuperviewGenerator : GeneratorType {

  typealias Element = UIView

  private var currentView: UIView? // or NSView on OS X, etc.
  
  private init(initialView: UIView?) {
currentView = initialView
  }
  
  mutating func next() -> Element? {
guard let here = currentView else {
  return nil
}
currentView = here.superview
return here
  }

}

// also e.g. analogous constructs for `CALayer`,
// `UIViewController`, `UIResponder`, “folders/directories”, and so on...
struct SuperviewSequence : SequenceType {

  typealias Generator = SuperviewGenerator
  
  private let initialView: UIView?
  
  init(initialView: UIView?) {
self.initialView = initialView
  }
  
  func generate() -> Generator {
return Generator(initialView: initialView)
  }
  
  func underestimateCount() -> Int {
return initialView != nil ? 1 : 0
  }
  
}

// Useful extensions:
extension UIView {

  // Enumerates the view hierarchy upward from `self`, including `self`.
  func inclusiveSuperviewSequence() -> SuperviewSequence {
return SuperviewSequence(initialView: self)
  }
  
  // Enumerates the view hierarchy upward from `self`, omitting `self`.
  func exclusiveSuperviewSequenc

Re: [swift-evolution] [Proposal] Make optional protocol methods first class citizens

2016-04-02 Thread plx via swift-evolution

> On Apr 1, 2016, at 7:37 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> Protocol requirements with default (no-op) implementations already satisfy 
>> that design goal, no?
> 
> Kind of. If I may steelman* optional members for a moment…

I’d actually go a bit further: for at least *some* of the uses of optional 
protocol methods, default implementations are necessary but not sufficient; to 
really “Swift-ify” without *losing* functionality you also would need to do a 
much-more-involved redesign of the protocol methods.

As just one example, I *think* the following API sketch is *adequate* for a 
Swift-ified` `tableView:heightForRowAtIndexPath:`:

  /// Mocked-up, "Swifty" table-view-delegate protocol:
  protocol TableViewDelegate : class {

/// Non-optional method, returning a "policy" enum that e.g. provides enough
/// information to the table view to let it choose the appropriate layout 
strategy...
func rowHeightPolicyForTableView(tableView: TableView) -> 
TableViewRowHeightPolicy

  }

  /// “How to calculate height” information for an entire table view.
  enum TableViewRowHeightPolicy {
  
/// all rows have identical height, table-view can operate in the "fast"
/// mode, like setting `tableView.rowHeight = $someHeight` w/o delegate.
case Uniform(CGFloat) 
  
/// table view should use auto-layout to measure each cell automatically;
/// like `tableView.rowHeight = UITableViewAutomaticDimension` w/o delegate.
case Automatic
  
/// get per-row height info from `RowHeightCalculator`; equivalent to your
/// having a delegate that implements `tableView:heightForRowAtIndexPath:`.
case Manual(RowHeightCalculator)

  }
  
  /// A dedicated “row-height-calculator” protocol. On the one hand, this could
  /// also be "just a closure", but promoting it into a protocol seems more 
  /// future-proof (e.g. if additional calculation-options become supported 
later).
  ///
  /// Unfortunately, making this an object means having to think harder than
  /// before about ownership issues; this seems mildly thorny.
  protocol RowHeightCalculator : class {
  
/// Returns the height-information for the given row; to *fully* recapture
/// existing `UITableView` functionality we need to return more than 
`CGFloat`.
func heightForRow(in tableView: UITableView, at indexPath: NSIndexPath) -> 
RowHeight
  
  }
  
  /// Height-calculation result for a single row.
  enum RowHeight {
  
/// Tells the table view to use auto-layout to measure this row's cell;
/// equivalent to *returning* `UITableViewAutomaticDimension`.
case Automatic 
  
/// Tells the table view to use the specified height for this row.
case Height(CGFloat)
  
  }

…and at least AIUI that’s a complete representation of the various 
row-height-related behaviors it’s possible arrive-at, today, via various 
combinations of “did you implement `tableView:heightForRowAtIndexPath:` or 
not?” and/or “are you setting/returning `UITableViewAutomaticDimension`?.

Note also that this is just the behavior for row-heights; to fully-cover 
today’s user-exposed functionality, you’d need to handle header-heights and 
footer-heights (which have similar methods/semantics), and probably also the 
estimated-height methods for rows, headers, and footers.

Pausing here for a moment, I think the above illustrates why the topic keeps 
coming up: although it’s certainly *possible* to get to the same place w/out 
optional protocol methods, it sometimes takes a bit of a design rethink to get 
there. The API surface also seems to get quite a bit larger; I think it’s fair 
to classify this as simply “making already-present complexity 
actually-visible”, but it’d still be bit of a shift.

For the actual `tableView:heightForRowAtIndexPath:` family I’m not sure what I 
think; I personally like a more-explicit approach as per the above, but once 
you start to include the header-and-footer heights and also the estimated 
height APIs, it gets to be a bit much; more so when you think about how this 
API looks with similar approaches for other currently-optional method “suites" 
(like highlight/selection management “suite", the menu/action “suite”, etc.).

To conclude, in many cases "optional methods => methods w/ reasonable default 
implementation” is all you need, but in *some* cases you would also need to 
design your API very differently to have equivalent functionality. 

I assume patterns and idioms for such designs will evolve over time, but at 
present there’s not a lot of Swift-ified datasource/delegate-style APIs out 
there to use for inspiration.

> -- 
> 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/li

Re: [swift-evolution] [Pitch] Moving where Clauses Out Of Parameter Lists

2016-04-06 Thread plx via swift-evolution
I don’t see much value in moving them out of the angle brackets but preserving 
the position; consider:

  // status-quo:
  func anyCommonElements  
(lhs: T, _ rhs: U) -> Bool
  
  // as-per proposal:
  func anyCommonElements 
where 
T.Generator.Element: Equatable, 
T.Generator.Element == U.Generator.Element
(lhs: T, _ rhs: U) -> Bool

…not very different! Or, if you want it with fewer lines:

  // status-quo:
  func anyCommonElements  
(lhs: T, _ rhs: U) -> Bool
  
  // as-per proposal:
  func anyCommonElements 
where T.Generator.Element: Equatable, T.Generator.Element == 
U.Generator.Element
(lhs: T, _ rhs: U) -> Bool

…still not very different!

Moving the `where` to come after “everything else" seems like an improvement 
for functions:

  func anyCommonElements (lhs: T, _ rhs: U) 
-> Bool
where 
T.Generator.Element: Equatable, 
T.Generator.Element == U.Generator.Element { 
  // body here...
}

…and presumably-also for type declarations:

  class SomeClass : BaseClass, SomeProtocol, AnotherProtocol
where
A.Something == SomethingElse,
B.Input == C.Output {

  }

..,but would take some getting-used-to.

Losing the ability to write `:` constraints inline in the brackets seems a 
non-starter, but perhaps constraints within the brackets could be limited to 
`:` constraints?

> On Apr 6, 2016, at 1:30 PM, Developer via swift-evolution 
>  wrote:
> 
> If you've ever gotten to the point where you have a sufficiently generic 
> interface to a thing and you need to constrain it, possibly in an extension, 
> maybe for a generic free function or operator, you know what a pain the 
> syntax can be for these kinds of operations.  For example, the Swift book 
> implements this example to motivate where clauses
> 
> func anyCommonElements  T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element> 
> (lhs: T, _ rhs: U) -> Bool
> 
> This is noisy and uncomfortable to my eyes, and almost impossible to align 
> correctly.  Per a short discussion on Twitter with Joe Groff and Erica Sadun, 
> I'd like so see what the community feels about moving the where clause out of 
> the angle brackets.  So that example becomes
> 
> func anyCommonElements 
> where T.Generator.Element: Equatable, T.Generator.Element == 
> U.Generator.Element
> (lhs: T, _ rhs: U) -> Bool
> 
> Or, if you're feeling ambitious, even
> 
> func anyCommonElements 
> where T : SequenceType, U : SequenceType,
> T.Generator.Element: Equatable, T.Generator.Element == U.Generator.Element
> (lhs: T, _ rhs: U) -> Bool
> 
> Thoughts?
> 
> ~Robert Widmann
> ___
> 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] [Re-Review] SE-0104: Protocol-oriented integers

2017-02-23 Thread plx via swift-evolution
+1 on most of it, with some minor quibbles.

First quibble: between `Number` and `Arithmetic` I’d prefer `Arithmetic`; this 
is 50/50 aesthetics and concern about clarity vis-a-vis `(NS)Number`, 
`(NS)DecimalNumber`, and so on.

Next quibble: `Magnitude` being defined as the “absolute value” of the 
underlying type seems a bit nonsensical if e.g. `Number` is intended to be 
adoptable by complex numbers (let alone quaternions, matrices, and whatnot). 
What *would* a conforming complex # implementation be expected to return as 
e.g. `(1-i).magnitude`? For the intended use this seems like it needs to be 
moved out of the basic `Number`/`Arithmetic` protocol into a new protocol.

Final quibble: is there an official stance as to whether or not 
`Number/`Arithmetic` is allowed to have non-commutative multiplication? I see 
would prefer any policy on this be explicitly documented.

If `Number`/`Arithmetic` *is* intended to allow adopters with non-commutative 
multiplication, then it’s seemingly missing an overridable method:

- this exists: `x *= y` (presumably equivalent to `x = x * y`)
- this doesn't: `x =* y` (presumably equivalent to one of `x = y * x` *or* `y = 
x * y`, your preference)

…(alternative operator names are fine, the important bit is an in-place 
multiplication-from-the-left). Not necessary, but still nice to have for 
non-commutative adoptees.

PS: I suspect this ship has *long* sailed but I suspect that it would be better 
in the long run to go the route of `Addable`, `Multipliable`, etc., and use 
typealiases to define common groupings thereof; note that once you remove 
`Magnitude`, the only difference between:

- `Number` (as defined)
- `typealias Number = Equatable & ExpressibleByIntegerLiteral & Addable & 
Multipliable`

…would be `init?(exactly source: T)`.

Although this is an extra method and thus extra “semantics”, I think there’s a 
perfectly-reasonable argument that—at least informally—the *semantics* of 
`init?(exactly source: T)` are already-implied by the 
adoption of `ExpressibleByIntegerLiteral`; in fact, are there any types that 
*could* reasonably adopt `ExpressibleByIntegerLiteral` but *could not* 
reasonably implement `init?(exactly source: T)`? 

Anyways, that’s my 2c on this: the Integer-related aspects seem fine, but I 
have quibbles vis-a-vis the foundational protocol.

> On Feb 17, 2017, at 7:45 PM, Joe Groff via swift-evolution 
>  wrote:
> 
> Hello Swift community,
> 
> The re-review of SE-0104 "Protocol-oriented integers" begins now and runs 
> through February 25, 2017. This proposal was accepted for Swift 3, but was 
> not implemented in time for the release. The revised proposal is available 
> here:
> 
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
>  
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at
> 
>   https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
>   Proposal link:
>   
> https://github.com/apple/swift-evolution/blob/master/proposals/0104-improved-integers.md
>   
>   Reply text
> 
>   Other replies
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   • What is your evaluation of the proposal?
>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   • Does this proposal fit well with the feel and direction of Swift?
>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at
> 
> https://github.com/apple/swift-evolution/blob/master/process.md
> 
> Thank you,
> 
> -Joe Groff
> Review Manager
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Re-Review] SE-0104: Protocol-oriented integers

2017-02-23 Thread plx via swift-evolution

> On Feb 23, 2017, at 11:31 AM, David Sweeris  wrote:
> 
> 
> On Feb 23, 2017, at 07:33, plx via swift-evolution  <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Next quibble: `Magnitude` being defined as the “absolute value” of the 
>> underlying type seems a bit nonsensical if e.g. `Number` is intended to be 
>> adoptable by complex numbers (let alone quaternions, matrices, and whatnot). 
>> What *would* a conforming complex # implementation be expected to return as 
>> e.g. `(1-i).magnitude`?
> 
> sqrt(2), I believe, or as close to it as can be represented by `Magnitude`

…which is what I’d expect if `x.magnitude` is supposed to be `||x||` or 
whatnot, but the stated motivation is:

  /// The magnitude of this value.
  ///
  /// For any numeric value `x`, `x.magnitude` is the absolute value of `x`.
  /// You can use the `magnitude` property in operations that are simpler to
  /// implement in terms of unsigned values, such as printing the value of an
  /// integer, which is just printing a '-' character in front of an absolute
  /// value.
  ///
  /// let x = -200
  /// // x.magnitude == 200

…for which uses the norm is not really helpful (and `Magnitude` not being 
`Comparable` is pretty annoying if it’s intended to be a norm; it really seems 
only intended to work as a generic tool for writing pretty-printers).

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


Re: [swift-evolution] Sequence/Collection Enhancements

2017-02-25 Thread plx via swift-evolution
Some belated feedback.

> On Feb 16, 2017, at 6:39 PM, Ben Cohen via swift-evolution 
>  wrote:
> Here is a list of commonly requested algorithms to operate on Sequence or 
> Collection:
> 
> In-place transformations:
> transform elements in a MutableCollection using a closure i.e. in-place map
+0.5 in the stdlib if only to side-step numerous re-implementations and perhaps 
also for minor performance gains.

+0.5 if it’s paired with an in-place variant (`mutating func mapInPlace(_ 
transform: (inout Element) -> Void) -> Void`); could perhaps be better-named 
`updateEach`.

Both are minor but would be nice-to-have as built-ins.

> remove(where:) that takes a predicate i.e. in-place filter
+2 as long as this is an overridable method. It’s a common need and difficult 
for users to write an efficient implementation.

One quibble: would this be on  `Collection`, `MutableCollection`, or some new 
`ShrinkableCollection`? This issue I’d have with putting this onto `Collection` 
itself is that that would seemingly shut the door on `Collection` being 
adoptable by any type that implements a “collection” with some fixed, intrinsic 
size.

Thus either adding it to `MutableCollection` (at cost of being overly narrow) 
or adding it to some new refinement like `ShrinkableCollection` (thus allowing 
e.g. `Set` and `Dictionary` to conform w/out eliminating fixed-size 
“collections” from adopting `Collection`).


> remove(indices:) that takes a Sequence of Index
+0 if *exactly* as stated; the point of a method like this would presumably be 
efficient bulk-removal, and a mere “a `Sequence` of `Index`” doesn’t provide 
much useful information: no count, no guarantee each index is included at-most 
once, no guarantee of ordering, and so on.

I think the “right” eventual solution is an equivalent to 
`(NS)IndexSet`—loosely speaking, a “collection” of non-empty, non-overlapping, 
ordered-ascending ranges of indices—but unfortunately it seems both difficult 
and premature to contemplate such a thing at this time.

> bulk operations (replace, remove, insert) on RangeReplaceableCollection for a 
> Sequence of subranges
See above: a `Sequence` of subranges is a bit better than a `Sequence` of 
`Index`, but doesn’t provide much information (# of ranges? # of indices? 
ranges ordered somehow? ranges non-overlapping? ranges non-empty?).

Thus for both of the previous two I strongly think building them around an 
`(NS)IndexSet`-like component is the way to do them but to do that 
`(NS)IndexSet`-alike type properly would IMHO be a bigger project than the 
current scope; in the absence of such an index-set type I’m not sure there’s 
enough benefit to these bulk operations to justify their inclusion.

> Select a random element of a RandomAccessCollection (note this could include 
> a random element of 0.. Check if all elements in a Sequence match a predicate (i.e. 
> !contains(!predicate))
+1, this in the stdlib is better than a million independent re-implementations.

As a philosophical point, I’d actually prefer if `all`, `any`, `notAll`, and 
`notAny` (change names to suit) were all in the stdlib even if just as 
convenience methods defined in an extension: no point having everyone roll 
their own and there’s likely a minor performance advantage if such code goes in 
the stdlib.

When only one “polarity” of a logical operation is available (`all` but not 
`none`, or `remove(where:)` but not `keep(where:)`, etc.) it seems inevitable 
to have occasional mismatches, and wrapping a closure in another closure just 
to apply `!` to it always at least “feels” wasteful. 

> reduce with an inout argument for the running value (PR for proposal here: 
> https://github.com/apple/swift-evolution/pull/587 
> )
+0.5? The performance consideration is real, but I’d hope the eventual 
ownership system would be able to mitigate the performance issues.

> rotation of elements in a collection (deferred proposal: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0078-rotate-algorithm.md
>  
> )
+0.5, it’s another nice thing to have in the standard library but not 
especially urgent. 

> Please reply here with any comments or questions on the above list, or any 
> additions you believe are important that are missing from it.
> As this focus area is larger in scope than Dictionary, it is likely that it 
> will need to be broken up into multiple separate proposals. The plan is to 
> get an initial high-level signal from this thread on which areas to put focus 
> on. We are also looking for volunteers to put together proposals and 
> implementations – if you're interested in helping with that, please email me 
> off-list. High quality community implementations will significantly improve 
> the chances of a feature making it into Swift 4. Smaller, more focussed 
> proposals are also more likely to make it than

Re: [swift-evolution] [Manifesto] Ownership

2017-02-25 Thread plx via swift-evolution
1: Collection Composition

As much as the high-level picture is focused on safety, I’d just like to 
request a strong focus on making sure the eventual ownership system addresses 
the common issues like avoiding copies when mutating through optionals, or when 
nesting collections, and so on.

Point fixes like the custom `.values` collection on `Dictionary` that just got 
approved are useful, but hopefully ownership can provide a general solution.

2: Mutating Iteration & Granularity

If I understood the mutating-iteration section right it reads as if `for inout` 
would only be available on `MutableCollection`. Is that correct?

If so that does seem limiting, as e.g. for a `Dictionary` it’d be nice if 
something like this were expressible:

  for (key, inout value) in someDictionary {
  }

…assuming there’s not some insurmountable technical obstacle.

3: Mutable Views

Currently a major pain point of Swift has been exposing “mutable views” into a 
type in a reasonable way. Apologies for length, but here’s an extended example:

  /// Implements a 2D grid (of size fixed upon initialization).
  /// **Not** a `Collection` itself but has many *views* into it that *are* 
`Collection`s.
  ///
  struct Grid2D {
// typical CoW backing storage
fileprivate var storage: Grid2DStorage

/// Obtain a linear traversal of our grid:
/// - parameter corner: The corner at which we start (e.g. `northWest`)
/// - parameter motion: The order in which we travel 
(`latitudeThenLongitude` or `longitudeThanLatitude`)
///
/// - returns: A read-only `Collection` that visits each grid location in 
`self`, following the requested traversal
func traversal(from corner: Grid2DCorner, following motion: Grid2DMotion) 
-> Grid2DTraversal
  }

…wherein `Grid2DTraversal` is, as noted, a "read-only view” into its parent 
that also adopts `Collection`.

What would be nice is to be able to make that `Grid2DTraversal` into a 
mutable view in a way that’s also *safe*; what I mean is something like:

  extension Grid2D {
  
mutating func mutatingTraversal(from corner: Grid2DCorner, following 
motion: Grid2DMotion, _ mutator: (inout Grid2DTraversal) -> R) -> R {
  var t = self.traversal(from: corner, following: motion)
  return mutator(&t)
}

  }

…with the specific goals of (a) having mutations applied via `Grid2DTraversal` 
get directly written-through to the underlying storage (w/out pointless 
copying) but also (b) making `Grid2DTraversal` generally act safely in all 
other contexts.

As it is the “best” way to squeeze this into the type system at this time is 
arguably:

- define Grid2DTraversal:
  - to have as a strong reference to the backing storage
  - as only having the read-only methods
- *also* define MutableGrid2DTraversal:
  - to have an unowned reference to the backing storage
  - also include the mutating methods

…and then just be careful with API design and patterns of use; in particular 
only provide access to `MutableGrid2DTraversal` values in the context of 
closures passed into dedicated functions like `mutatingTraversal`, above…and 
then just be disciplined never to extract those passed-in values.

Needless to say this isn’t a very satisfactory state of affairs—it is well into 
“why am I bothering with all this?” territory—and it’d be *far* nicer if the 
ownership system would allow for `Grid2DTraversal`:

- to adopt `Collection` without restriction
- to adopt `MutableCollection` only in certain ownership contexts
- to have reasonable control over where those contexts apply 

Anyways, it’s not clear to me, personally, whether or not the above is within 
the scope of any likely, concrete ownership system that’d follow from the 
manifesto or not…but if at all possible I’d prefer the eventual ownership 
system make it reasonable—and reasonably safe—to implement “small-c 
‘collection’s that can safely-and-efficiently expose various *mutable* views as 
big-C `Collection`s”.

Apologies if all of the above considerations have answers that follow trivially 
from the manifesto; it’s just unclear personally whether the features described 
in the manifesto would work together to allow something like the above to be 
implemented more-reasonably than currently the case.

> On Feb 17, 2017, at 11:08 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On Feb 17, 2017, at 4:50 AM, Adrian Zubarev > > wrote:
>> Hi John, would you mind creating a markdown document for this manifesto in 
>> https://github.com/apple/swift/tree/master/docs 
>> ? :)
>> 
>> 
> Yes, it should go in the repository.  That commit is pending, but the in 
> meantime, you can see the document properly rendered at:
>   
> https://github.com/rjmccall/swift/blob/4c67c1d45b6f9649cc39bbb296d63663c1ef841f/docs/OwnershipManifesto.md
>  
> 

Re: [swift-evolution] [Manifesto] Ownership

2017-03-07 Thread plx via swift-evolution

> On Feb 27, 2017, at 11:08 AM, John McCall  wrote:
> 
>> On Feb 25, 2017, at 11:41 AM, plx via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 1: Collection Composition
>> 
>> As much as the high-level picture is focused on safety, I’d just like to 
>> request a strong focus on making sure the eventual ownership system 
>> addresses the common issues like avoiding copies when mutating through 
>> optionals, or when nesting collections, and so on.
> 
> Avoiding copies is basically the entire core of the proposal.  The 
> interaction with safety is that sometimes copies are necessary to avoid 
> memory unsafety, and this proposal recommends an approach that minimizes that.

Thanks for the extend reply and sorry for my own belated reply.

What motivated me to ask for more focus on the common cases was that it was 
unclear from reading the proposal whether the `inout` binding--as used in `for 
inout`--could be used with `if`: in other words, we currently have `if let` and 
`if var`, but will we have `if inout` under this proposal?

I am embarassed to admit I honestly couldn't tell if the proposal didn't 
contain any examples of `if inout` due to (a) the capability following 
trivially from the rest of the proposal or (b) the capability falling outside 
the scope of the proposal.

If it's (a) I apologize and feel free to skip down to the next section, if it's 
(b) I'll reiterate my request to for more focus on streamlining the common 
cases. In particular it'd be nice if there was a relatively homogeneous syntax 
as sketched below:

 for related operations starts to diverge a bit:

  var dict: [K:Set] = // ...
  
  // read-only uses `if-let` (or `if shared`?)
  if let setForKey = dict[key] {
// read `setForKey`
  }
  
  // simple in-place mutation
  if inout setForKey = dict[key] {
setForKey.mutateSomehow()
  }
  
  // compound "in-place" mutation 
  if inout setForKey = dict[key] {
setForKey.mutateSomehow()
setForKey.mutateSomeOtherWay()
  }

  // simple "in-place" mutation w/follow-up
  if inout setForKey = dict[key] {
setForKey.mutateSomehow()
let shouldRemove = setForKey.isEmpty
endScope(setForKey)
if shouldRemove {
  dict.removeValue(forKey: key)
}
  }

  // compound "in-place" mutation w/follow-up
  if inout setForKey = dict[key] {
setForKey.mutateSomehow()
setForKey.mutateSomeOtherWay()
let shouldRemove = setForKey.isEmpty
endScope(setForKey)
if shouldRemove {
  dict.removeValue(forKey: key)
}
  }
  
...which, again, all use approximately the same syntax for each of these 
scenarios. 

Contrast with what would be the ideal ways to write the above under the 
proposal AIUI:

  var dict: [K:Set] = // ...
  
  // read-only uses `if-let` (or `if shared`?)
  if let setForKey = dict[key] {
// read `setForKey`
  }
  
  // simple in-place mutation
  if let index = dict.index(of: key) {
dict.values[index].mutateSomehow()
  }
  
  // compound "in-place" mutation, I
  // shorter, less-efficent due to repeated lookup
  if let index = dict.index(of: key) {
dict.values[index].mutateSomehow()
dict.values[index].mutateSomeOtherWay()
  }

  // compound "in-place" mutation, II
  // longer, more-efficent
  if let index = dict.index(of: key) {
inout setForKey = &dict.values[index]
setForKey.mutateSomehow()
setForKey.mutateSomeOtherWay()
  }

  // simple "in-place" mutation w/follow-up, I
  // longer, less-efficient due to repeated lookup
  if let index = dict.index(of: key) {
dict.values[index].mutateSomehow()
if dict.values[index].isEmpty {
  dict.remove(at: index)
}
  }

  // simple "in-place" mutation w/follow-up, II
  // longer, less-efficient due to repeated lookup
  if let index = dict.index(of: key) {
inout setForKey = &dict.values[index]
setForKey.mutateSomehow()
let shouldRemove = setForKey.isEmpty
endScope(shouldRemove)
if shouldRemove {
  dict.remove(at: index)
}
  }

  // compound "in-place" mutation w/follow-up, I
  // longer, less-efficient due to repeated lookups
  if let index = dict.index(of: key) {
dict.values[index].mutateSomehow()
dict.values[index].mutateSomeOtherWay()
if dict.values[index].isEmpty {
  dict.remove(at: index)
}
  }

  // compound "in-place" mutation w/follow-up, II
  // longer, less-efficient due to repeated lookup
  if let index = dict.index(of: key) {
inout setForKey = &dict.values[index]
setForKey.mutateSomehow()
setForKey.mutateSomeOtherWay()
let shouldRemove = setForKey.isEmpty
endScope(shouldRemove)
if shouldRemove {
  dict.remove(at: index)
}
  }

...where my concern is less about what how particular scenario winds up looking 
and more that there’s such variance *betwee