[swift-evolution] Handling unknown cases in enums [RE: SE-0192]

2018-01-12 Thread Rex Fenley via swift-evolution
Hey Jordan, coming into this a bit late, but it seems like `case #unknown`
is the more flexible syntax regardless of warning or error. If typed errors
are added then it would fall cleanly into catch pattern matching as well it
sounds like. Any thoughts there?

And for the record I'm slightly in favor of an error on unknown matches.
I'm just not sure that breaking source compatibility has been an issue with
enums thus far. It'd be my own preference to throw an error if I intend for
a type to be exhaustively matched, though I can definitely be ok with just
a warning too.

Okay, I went back to `unknown case` in the proposal, but mentioned Chris's
> point very specifically: if the compiler emits an error, we should go with
> `case #unknown` instead. (I'm very strongly in the "warning" camp, though.)



I think the revised proposal is in good shape! (
> https://github.com/apple/swift-evolution/pull/777) I think I've addressed
> everyone's feedback either in the proposal or on-list, if not necessarily
> convinced them. If there are no other major comments I'll let Ted know that
> it's ready to re-run on Monday. Jordan


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] [Pitch] Generalized supertype constraints

2018-01-10 Thread Rex Fenley via swift-evolution
Have you found anyone else to help on this one? I would like to dive in
myself but I don't have any experience with the compiler and not sure about
the size of the workload here.

On Tue, Dec 5, 2017 at 3:34 PM, Rex Fenley  wrote:

> Huge +1, I've asked for this in the past too.
>
> Have you also found this limitation frustrating?
>   - Yes
>
> In what contexts?
>   - APIs that have this requirement and end up enforcing them through
> runtime type checking and throws. Shows up in some network data mapping
> code I have that generalizes over Core Data and Realm (and other
> databases). The protocol implementer must specify the subtype for the raw
> mapping of JSON and base type for the DB reading/writing layer. Could see
> this showing up whenever there's a separation of concerns between what
> business logic belongs to the base type and subtypes of a more generalized
> system. I could potentially see the same issue showing up in code
> generalizing the mapping of data to UI, like UITableView/UITableViewCell.
>
> Does anyone have reservations about introducing this capability?
>   - I do not
>
> One of the most frequent frustrations I encounter when writing generic
> code in Swift is the requirement that supertype constraints be concrete.
> When I mentioned this on Twitter (https://twitter.com/anandabit
> s/status/929958479598534656) Doug Gregor mentioned that this feature is
> smaller and mostly straightforward to design and implement (
> https://twitter.com/dgregor79/status/929975472779288576).
>
> I currently have a PR open to add the high-level description of this
> feature found below to the generics manifesto (
> https://github.com/apple/swift/pull/13012):
>
> Currently, supertype constraints may only be specified using a concrete
> class or protocol type.  This prevents us from abstracting over the
> supertype.
>
> ```swift
> protocol P {
>   associatedtype Base
>   associatedtype Derived: Base
> }
> ```
>
> In the above example `Base` may be any type.  `Derived` may be the same as
> `Base` or may be _any_ subtype of `Base`.  All subtype relationships
> supported by Swift should be supported in this context including, but not
> limited to, classes and subclasses, existentials and conforming concrete
> types or refining existentials, `T?` and  `T`, `((Base) -> Void)` and
> `((Derived) -> Void)`, etc.
>
> Generalized supertype constraints would be accepted in all syntactic
> locations where generic constraints are accepted.
>
> I would like to see generalized supertype constraints make it into Swift 5
> if possible.  I am not an implementer so I will not be able to bring a
> proposal forward alone but am interested in collaborating with anyone
> interested in working on implementation.
>
> I am also interested in hearing general feedback on this feature from the
> community at large.  Have you also found this limitation frustrating?  In
> what contexts?  Does anyone have reservations about introducing this
> capability?  If so, what are they?
>
> Matthew
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
> --
>
> Rex Fenley  |  IOS DEVELOPER
>
> Remind.com  |  BLOG   |
>  FOLLOW US   |  LIKE US
> 
>



-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] [Review] SE 0192 - Non-Exhaustive Enums

2017-12-21 Thread Rex Fenley via swift-evolution
I agree with everything said by Brent Royal-Gordon, however a -1 without
the addition of a `future` case or something similar.

   -

   What is your evaluation of the proposal?

-1, this solution solves a real problem but introduces a very significant
drawback. It should include a solution that preserves exhaustive pattern
matching for the user.

   -

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

Yes, absolutely.

   -

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

Feels like 1 step forward and 1 step back. Solves a real problem and
introduces a real new one.

   -

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

Rust settled on exhaustive as the default case, signaling the importance of
preserving exhaustive pattern matching. I've run into bugs in Objective-C,
where there is no exhaustive pattern matching, and that's been a pain -
since enums are more powerful in Swift the consequences may be worse.

   -

   How much effort did you put into your review? A glance, a quick reading,
   or an in-depth study?

I've actively participated in previous discussions on the topic, and read
the proposal top-to-bottom for this review. I leverage enums and exhaustive
pattern matching significantly in my own code.

> On Dec 20, 2017, at 10:16 PM, Brent Royal-Gordon via swift-evolution <
swift-evolution@swift.org> wrote:
>
>> On Dec 19, 2017, at 2:58 PM, Ted Kremenek via swift-evolution <
swift-evolution@swift.org> wrote:
>>
>>  • What is your evaluation of the proposal?
>
> I am pleased with the broad strokes of this design. I have quibbles with
three areas:
>
> 1. The `@exhaustive` attribute may be confusing because the term doesn't
suggest versioning. My best alternative suggestion is `@frozen`, which
matches existing programming terminology: something that has been frozen
will not be changed in the future.
>
> 2. I think we need some kind of `future` keyword in `switch` statements.
Even though a nonexhaustive enum may gain additional cases in the future,
it's still useful for the compiler to diagnose that you forgot *known*
cases.
>
> You say that "switches over non-exhaustive enums should be uncommon", and
this is true for many—perhaps most—non-exhaustive enums, but there is still
a large class of non-exhaustive enums which need to be switched over. These
are the ones I called "category 2" in my previous email in this thread.
`SKPaymentTransactionState` is the example I previously used; others might
include `Stream.Status` (if not exhaustive), `CLAuthorizationStatus`,
`EKParticipantType`, `PKPaymentMethodType`, and `MKMapType`. Each of these
could plausibly have more cases added; each has a good reason why you might
switch over cases (such as display in a user interface); and each ought to
be promptly updated when a new OS version introduces new cases. Without
compiler assistance, those updates won't happen.
>
> If we plan to add private cases in a future version of Swift, `future`
may not be the best keyword. `unknown`, `invalid` (or `case #invalid`),
etc. may be better.
>
> 3. I am very skeptical of treating all enums as exhaustive if imported by
`@testable import`. The only reason I can see not to do this is that
forcing you to provide `default` might hide tests that need to be updated
for new enum cases—but this is the exact problem that `future` is trying to
solve. By contrast, treating them as non-exhaustive forces you to actually
notice when an enum is published as nonexhaustive and consider whether
that's the right approach.
>
> None of these are showstoppers if left unaddressed, but I think the
design would be better if we fixed them.
>
>>  • Is the problem being addressed significant enough to warrant a
change to Swift?
>
> Yes. I have no idea how Swift programs currently behave when a future
framework version adds a case, but I can't imagine they do anything good.
>
>>  • Does this proposal fit well with the feel and direction of Swift?
>
> Yes, with the exception of conflating `default` and `future`, which
removes useful correctness checks.
>
>>  • If you have used other languages or libraries with a similar
feature, how do you feel that this proposal compares to those?
>
> I've experienced bugs in Objective-C caused by the compiler not knowing
an enum might have additional, unknown cases. Debugging them sucked.
>
>>  • How much effort did you put into your review? A glance, a quick
reading, or an in-depth study?
>
> I've participated in multiple rounds of discussion on this topic, and
read the proposal top-to-bottom for this review.
>
> --
> Brent Royal-Gordon
> Architechies
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 

[swift-evolution] [Pitch] Generalized supertype constraints

2017-12-05 Thread Rex Fenley via swift-evolution
Huge +1, I've asked for this in the past too.

Have you also found this limitation frustrating?
  - Yes

In what contexts?
  - APIs that have this requirement and end up enforcing them through
runtime type checking and throws. Shows up in some network data mapping
code I have that generalizes over Core Data and Realm (and other
databases). The protocol implementer must specify the subtype for the raw
mapping of JSON and base type for the DB reading/writing layer. Could see
this showing up whenever there's a separation of concerns between what
business logic belongs to the base type and subtypes of a more generalized
system. I could potentially see the same issue showing up in code
generalizing the mapping of data to UI, like UITableView/UITableViewCell.

Does anyone have reservations about introducing this capability?
  - I do not

One of the most frequent frustrations I encounter when writing generic code
in Swift is the requirement that supertype constraints be concrete.  When I
mentioned this on Twitter (https://twitter.com/anandabits/status/
929958479598534656) Doug Gregor mentioned that this feature is smaller and
mostly straightforward to design and implement (https://twitter.com/
dgregor79/status/929975472779288576).

I currently have a PR open to add the high-level description of this
feature found below to the generics manifesto (https://github.com/apple/
swift/pull/13012):

Currently, supertype constraints may only be specified using a concrete
class or protocol type.  This prevents us from abstracting over the
supertype.

```swift
protocol P {
  associatedtype Base
  associatedtype Derived: Base
}
```

In the above example `Base` may be any type.  `Derived` may be the same as
`Base` or may be _any_ subtype of `Base`.  All subtype relationships
supported by Swift should be supported in this context including, but not
limited to, classes and subclasses, existentials and conforming concrete
types or refining existentials, `T?` and  `T`, `((Base) -> Void)` and
`((Derived) -> Void)`, etc.

Generalized supertype constraints would be accepted in all syntactic
locations where generic constraints are accepted.

I would like to see generalized supertype constraints make it into Swift 5
if possible.  I am not an implementer so I will not be able to bring a
proposal forward alone but am interested in collaborating with anyone
interested in working on implementation.

I am also interested in hearing general feedback on this feature from the
community at large.  Have you also found this limitation frustrating?  In
what contexts?  Does anyone have reservations about introducing this
capability?  If so, what are they?

Matthew

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


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


[swift-evolution] [Pitch] Generic associatedtype subtype constraints

2017-10-24 Thread Rex Fenley via swift-evolution
Currently you can constrain a type parameter via a generic using equality

protocol A {
associatedtype T where T == BKind.V
associatedtype BKind: B
}

protocol B {
associatedtype V
}


However, you cannot do the following

associatedtype T where T: BKind.V

Could this be added to the language? Is there a reason something like this
would not be sound?

My use case would look like the following

protocol Mapping {
associatedtype MappedObject: DatabaseAdapterKind.BaseType
associatedtype DatabaseAdapterKind: DatabaseAdapter

...
}

protocol DatabaseAdapter {
associatedtype BaseType

...
}


For Realm Obj-C fulfillment would look like the following

// User is an RLMObject subtype

protocol UserMapping: Mapping {
typealias MappedObject = User
typealias DatabaseAdapterKind = RealmAdapter

// ... functions
}

protocol RealmAdapter: DatabaseAdapter {
typealias BaseType = RLMObject

// ... functions
}


For CoreData replace RLMObject with NSManagedObject

The mapping system allows the developer to write a mapping from JSON to a
type (MappedObject). Given that the type of MappedObject is a subtype of
the BaseType of the DatabaseAdapter the system will write an object of type
MappedObject to the database. This setup works with Realm Obj-C,
RealmSwift, and Core Data all of which have different BaseTypes but use
subtyping from a BaseType to specify the Model/MappedObject that is stored
in the db.

I can't use MappedObject == DatabaseAdapterKind.BaseType because this needs
to be a subtyping relation. E.g. a User: NSManagedObject is true but User
== NSManagedObject is not.

Since I can't specify this subtype relation in the protocol I end up having
to do runtime type checking and as! casts in quite a few places which seems
unnecessary and error prone during refactoring.

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] Enums and Source Compatibility

2017-09-22 Thread Rex Fenley via swift-evolution
>
> It’s really only an issue for people whose frameworks are used across
> variously-distributed apps (your own, or other peoples’). The typical
> dynamic library use-case. Those people already know to be careful, so why
> make non-exhaustive the default for everybody? It’s a fair point.
>


> Getting this right can be pretty hard. For example, I expect that
> @_inlineable functions within the enum’s declaring module will also be
> affected by this (a client could inline the code, then you add an enum
> case…). At the same time, it’s difficult for a shared library vendor to say
> definitively that a particular enum will never change (unless it really is
> a very simple thing, like NSComparisonResult) - almost anything with
> meaning to how the library works is usually subject to change in case
> edge-cases are discovered. The analysis of Apple’s frameworks is good data
> to prove it, but it also makes sense that vendors like to retain as much
> implementation freedom as possible.


Just for clarity, this seems like the binary compatibility piece correct?
As far as I understand this could only affect a dynamically linked library,
but if you're linking a library dynamically, how could you inline a
function, since if it's dynamically linked you don't know what to inline?

Also, I've never heard of these kinds of issues in other languages with
exhaustive pattern matching. Would be very interested to know how OCaml or
Haskell solve this problem?

Thanks for your input


On Fri, Sep 22, 2017 at 8:20 AM, Karl Wagner  wrote:

>
> On 21. Sep 2017, at 00:51, Rex Fenley via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi Jordan,
>
> I've been keeping up with most of the discussion since I last emailed
> about my concern about making nonexhaustive the default mode for enums. So
> far I am still strongly in the camp of exhaustive by default.
>
> Most of my understanding comes from the perspective of source
> compatibility; since I'm primarily an iOS app developer and contributor to
> open source through CocoaPods, I don't have enough experience with binary
> compatibility issues to understand the breadth of the effects of such a
> change on binary compatibility - so I will argue from the perspective of
> source compatibility. Additionally, all the following applies exclusively
> to enums from Swift and not Obj-C/C. Largely my concerns stem from the 
> "default
> effect <https://en.m.wikipedia.org/wiki/Default_effect_(psychology)>"-
> whatever default is chosen is going to unconsciously bias developers to use
> that default.
>
> To start, I don't follow how nonexhaustive by default leads to more secure
> code or promises less. In a world where nonexhaustive is default,
> hard-to-track bugs will be introduced frequently into many Swift
> developer's code.
>
>- Evolving contracts - The change you suggest leaves it up to the user
>to remember to add new cases into their code if an enum ever does change in
>a framework, and their code relies on exhaustive pattern matching.
>
> I think this is the right thing to do. Library vendors can still
> communicate changes with clients through deprecation notices. Ultimately it
> is up to the vendor to maintain compatibility for people switching against
> those older cases, and up to the clients to adopt any new behaviour that
> gets implemented.
>
>
>- Unhandled case bugs - This will lead to inconsistencies and
>hard-to-track bugs, since it would require the user to then track down an
>unhandled case that they may not even be aware exists (forcing googling,
>searching through documentation, etc.).
>
> This is something that I certainly have experienced in the past working
> across teams programming in Obj-C, and Swift has so far completely
> eliminated this class of bugs! In a world where exhaustive remains default,
> nothing changes, fewer bugs.
>
>
> I’m not sure that those issues are so difficult to track down. You’ll know
> that switch statements which fall-through to a default case are suspicious
> - but they already are today, too!. It’s not really any different to having
> allowing singular “if”s without a corresponding “else”. I could also see
> the debugging value in a “future” case label, but it’s not necessary IMO.
>
> Although, I can kind of see your point:
>
> If you’re talking about a private framework (e.g. the multi-module App
> scenario), then things are a little different for you because typically,
> you’ll ship new versions of the framework and App together. The framework
> can be as fragile as you like in that case - you can break all the ABI
> stability rules, because there will no apps importing the new version of
> th

Re: [swift-evolution] Enums and Source Compatibility

2017-09-20 Thread Rex Fenley via swift-evolution
Hi Jordan,

I've been keeping up with most of the discussion since I last emailed about
my concern about making nonexhaustive the default mode for enums. So far I
am still strongly in the camp of exhaustive by default.

Most of my understanding comes from the perspective of source
compatibility; since I'm primarily an iOS app developer and contributor to
open source through CocoaPods, I don't have enough experience with binary
compatibility issues to understand the breadth of the effects of such a
change on binary compatibility - so I will argue from the perspective of
source compatibility. Additionally, all the following applies exclusively
to enums from Swift and not Obj-C/C. Largely my concerns stem from the "default
effect "-
whatever default is chosen is going to unconsciously bias developers to use
that default.

To start, I don't follow how nonexhaustive by default leads to more secure
code or promises less. In a world where nonexhaustive is default,
hard-to-track bugs will be introduced frequently into many Swift
developer's code.

   - Evolving contracts - The change you suggest leaves it up to the user
   to remember to add new cases into their code if an enum ever does change in
   a framework, and their code relies on exhaustive pattern matching.
   - Unhandled case bugs - This will lead to inconsistencies and
   hard-to-track bugs, since it would require the user to then track down an
   unhandled case that they may not even be aware exists (forcing googling,
   searching through documentation, etc.).

This is something that I certainly have experienced in the past working
across teams programming in Obj-C, and Swift has so far completely
eliminated this class of bugs! In a world where exhaustive remains default,
nothing changes, fewer bugs.

Next off is developer usability. As someone who has contributed to several
frameworks in Swift, one thing I know is that you can always count on
people complaining about the usability of their library - it's something
you learn to expect. If it turns out that people are very frustrated with
an enum constantly changing and breaking compatibility, they will voice
that concern with a thousand 👍 on github, debate will happen, and the
appropriate course correction will be made. In this case, no real damage
done.

That said, if enums are nonexhaustive by default, frameworks will have more
nonexhaustive enums (as it becomes convention). The class of bugs
previously discussed will emerge, causing real damage to users and
developers. Complaints will arise, but with more hostility. In this case,
we end up back where we started, since framework developers will then mark
exhaustive for all their enums. The only difference is that it'll be
something that must be remembered to be done.

I can understand how someone developing an Apple framework may want
nonexhaustive by default, since enums from some Apple libraries seem to be
much larger and change relatively often. Yet, from my experience, this
doesn't represent what you find in open source libraries that seem to land
on something consistent and then stick with it. And that consistency pairs
very well with exhaustiveness.

Given this, it's clear that adding a case to an enum as a source breaking
change should be the expected behavior. It's safer for those using the
frameworks, and back propagation from users will correct it if it becomes
an annoyance. Nonexhaustive as a keyword is a nice additional tool to make
this correction simpler (as well as protect C enums by default), but should
not be the standard.

Best,
Rex

On Fri, Sep 15, 2017 at 5:06 PM, Jordan Rose  wrote:

> Hi, Rex. I definitely agree that 'exhaustive' is the right model for a
> multi-module app; indeed, there's no real reason for a single project to do
> anything else. However, it is not always the right behavior for libraries
> that actually get distributed, whether as source or as binary. In this case
> we want to minimize the error of omission: in the app case, forgetting
> "exhaustive" is an annoyance that you notice and fix once across your code
> base, but in the library case forgetting the "default case" means putting
> out a source-breaking release, and for libraries that have binary
> compatibility constraints there's no recourse at all.
>
> While most of the proposal deals with the experience we've had with the
> Apple SDKs (as written in Objective-C), we actually *have* run into this
> case in Swift already. The Swift Playgrounds app comes with a framework,
> PlaygroundSupport, that can be used from within a playground. It's
> important that when they upgrade the app, existing playgrounds don't break,
> since the end user may not have access to the entire code of the
> playground. (Remember that playgrounds are often authored by one developer
> or group, but then run and modified by someone else with a much lower skill
> level!) *That* means that PlaygroundSupport can't currently

[swift-evolution] Enums and Source Compatibility

2017-09-15 Thread Rex Fenley via swift-evolution
Hey Jordan,

Thank you for the time writing this up. I've been following along to the
discussion somewhat closely and have kept silent because `exhaustive` was
originally set to be the default for enums. However, that changed and so
I'd like to voice my opinion, I frankly don't like this idea.

At remind we use algebraic data types religiously for managing state and
data and rely on exhaustive pattern matching to guarantee we're handling
all states in our code. We're splitting out our code across modules and
having this guarantee has been a joy to work with.

The benefit of making nonexhaustive the default for Swift 5 across all
multi-module code (besides C code) seems minimal to me. If a developer
feels like they're unnecessarily managing enum cases, they can simply add a
`default` case whenever they please. This is already the case and I'm
curious if there's every been any complaints about this and what they would
be. I'd prefer to be cautious and force exhaustive pattern matching in all
possible cases and leave it up to the developer to choose not to.

Ideally in my mind, these keywords won't be necessary. All Swift enums will
remain as they are, exhaustively pattern matched by default. Enums from C
code will be explicitly nonexhaustive in all cases.

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] [Review] SE-0166: Swift Archival & Serialization

2017-04-10 Thread Rex Fenley via swift-evolution
How exactly does that work from the perspective of the initializer if you
have 2 sets of keys to choose from? Would I extend the initializer to
include my feature flag `public init(from decoder: Decoder, flag: Bool)
throws` and switch on that? Or could I pass in the Container I want to use
somehow, which seems cleaner to me as an abstraction? (This is similar to
what we're already doing with the setup we have.) How does a key jump
multiple levels "permissions.can_send_message" and is there a way to know
ahead of time which key maps to what property? Needing to express every
possible mapping from the initializer seems clumsy to me and I think would
fit better as a part of the Container itself.

On Mon, Apr 10, 2017 at 3:13 PM, Tony Parker 
wrote:

> Hi Rex,
>
> On Apr 10, 2017, at 12:48 PM, Rex Fenley via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Forgive me if I'm missing something, this is a very large proposal and a
> lot to parse through. I like how everything is designed as far as I can
> tell except I'm not sure from this proposal how one would compose multiple
> different types of Decoders against the same output type. For example, with
> Location we have.
>
> // Continuing examples from before; below is automatically generated by
> the compiler if no customization is needed.
> public struct Location : Codable {
> private enum CodingKeys : CodingKey {
> case latitude
> case longitude
> }
>
> public init(from decoder: Decoder) throws {
> let container = try decoder.container(keyedBy: CodingKeys.self)
> latitude = try container.decode(Double.self, forKey: .latitude)
> longitude = try container.decode(Double.self, forKey: .longitude)
> }
> }
>
> However, this initializer seems strictly tied to the `CodingKeys` set of
> coding keys. From what it appears, if this was used to decode from JSON the
> format would have to always be:
>
> {
> "latitude" : 20.0
> "longitude" : 20.0
> }
>
> I have a use case we're on my client we began the process of switching
> from one version of an API to another. In one version we had a payload
> similar to
>
> {
> "user" : {
> "uuid" : "uuid string..."
> "can_send_message" : true
> "can_delete_message" : false
> }
> }
>
> this would result in the following Codable (from "user") from what I'm
> following
>
> public struct User : Codable {
> private enum CodingKeys : CodingKey {
> case uuid
> case can_send_message
> case can_delete_message
> }
>
> public init(from decoder: Decoder) throws {
> let container = try decoder.container(keyedBy: CodingKeys.self)
> uuid = try container.decode(Double.self, forKey: .uuid)
> canSendMessage = try container.decode(Bool.self, forKey:
> .can_send_message)
> canDeleteMessage = try container.decode(Bool.self, forKey:
> .can_delete_message)
> }
> }
>
> when we began switching over to the new api the payload was returned as
>
> {
> user {
> "uuid" : "uuid string..."
> "permissions" : {
> "can_send_message" : true
> "can_delete_message" : false
> }
> }
> }
>
> Here with "permissions" we have a new internal container with a separate
> set of coding keys. Issue is in my use case I still need to maintain a way
> to decode the old version simultaneously; we guard all new changes behind
> feature flags in case something goes awry and we need to roll back our
> changes.
>
> How would one go about expressing this new Decoding and the previous
> Decoding simultaneously on the same User type?
>
>
> You would fall out of the automatically-generated scenario here, but this
> use case is exactly what the ‘container’ API is for. You can create a
> container with a new set of keys, then decode from it.
>
> Another approach would be to create a nested type that conforms with
> Codable which represents the “permissions” as a type of its own.
>
> - Tony
>
>
>
> --
> Rex Fenley  |  IOS DEVELOPER
>
> Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>  |
>  FOLLOW US <https://twitter.com/remindhq>  |  LIKE US
> <https://www.facebook.com/remindhq>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0166: Swift Archival & Serialization

2017-04-10 Thread Rex Fenley via swift-evolution
Forgive me if I'm missing something, this is a very large proposal and a
lot to parse through. I like how everything is designed as far as I can
tell except I'm not sure from this proposal how one would compose multiple
different types of Decoders against the same output type. For example, with
Location we have.

// Continuing examples from before; below is automatically generated by the
compiler if no customization is needed.
public struct Location : Codable {
private enum CodingKeys : CodingKey {
case latitude
case longitude
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
latitude = try container.decode(Double.self, forKey: .latitude)
longitude = try container.decode(Double.self, forKey: .longitude)
}
}

However, this initializer seems strictly tied to the `CodingKeys` set of
coding keys. From what it appears, if this was used to decode from JSON the
format would have to always be:

{
"latitude" : 20.0
"longitude" : 20.0
}

I have a use case we're on my client we began the process of switching from
one version of an API to another. In one version we had a payload similar to

{
"user" : {
"uuid" : "uuid string..."
"can_send_message" : true
"can_delete_message" : false
}
}

this would result in the following Codable (from "user") from what I'm
following

public struct User : Codable {
private enum CodingKeys : CodingKey {
case uuid
case can_send_message
case can_delete_message
}

public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
uuid = try container.decode(Double.self, forKey: .uuid)
canSendMessage = try container.decode(Bool.self, forKey:
.can_send_message)
canDeleteMessage = try container.decode(Bool.self, forKey:
.can_delete_message)
}
}

when we began switching over to the new api the payload was returned as

{
user {
"uuid" : "uuid string..."
"permissions" : {
"can_send_message" : true
"can_delete_message" : false
}
}
}

Here with "permissions" we have a new internal container with a separate
set of coding keys. Issue is in my use case I still need to maintain a way
to decode the old version simultaneously; we guard all new changes behind
feature flags in case something goes awry and we need to roll back our
changes.

How would one go about expressing this new Decoding and the previous
Decoding simultaneously on the same User type?


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


[swift-evolution] where clauses on enum cases

2017-03-14 Thread Rex Fenley via swift-evolution
I've run into a problem recently when using generics with enums where I'm
required to specify the type for a generic that isn't used for the enum
case that's constructed.

Example:

protocol Mapping {
associatedtype Destination
}

enum EvictionPolicy {
case append
case replace
}

enum Map where U.Destination: Collection {
case object(T)
case collection(U, EvictionPolicy)
}

class IntMapping: Mapping {
typealias Destination = Int
}

class IntsMapping: Mapping {
typealias Destination = [Int]
}

// Must specify types for generics that are not in use
let o = Map.object(IntMapping())
let c = Map.collection(IntsMapping(),
EvictionPolicy.append)

What I'd like to be able to do is the following

enum Map {
case object(T)
case collection(T, EvictionPolicy) where T.Destination: Collection
}

Could this be added to the language?

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] 'T != Type' in where clause

2017-02-28 Thread Rex Fenley via swift-evolution
Here's a simplified section of code I'm writing for mapping some data from
over the wire


public protocol Transform {
// a bunch of stuff
}

public protocol Key {
// a bunch of stuff
}

extension String: Key { /* conforming stuff */ }

public protocol JSONType { }
extension Int: JSONType { }

public enum Bind: Key {
case transform(Key, T)
// a few more cases, every case must have a Key, we forward all of
Key's methods through each case.
}

public func map(field: inout T, binding: Key) {
print(field)
}

public func map(field: inout T, binding: Bind) {
print(field)
}

class SpecialTransform: Transform { }

var s = Int()
// Ambiguity here.
map(field: &s, binding: Bind.transform("data.stuff", SpecialTransform()))


Probably would be better to make `Bind` not conform to `Key`, would just
require a bunch of refactoring in places where I've used the two
interchangeably. However, one of the benefits of having `Bind: Key` is that
it enforces that every additional case has a `Key` which will always be
true for this data structure.

I was thinking the first `map` would change  to

public func map(field: inout T, binding: K)


But to have `K != Bind`, Bind would have to be the super type of
all other Binds which currently isn't true anyway so this is kind of
dead on arrival.

Interestingly though, when I change the signature to

public func map(field: inout T, binding: K)


Instead of "Ambiguous use of...", the program compiles and calls this
method instead of the overload with Bind. Not only is this not the
function I want called, but this seems like inconsistent behavior with the
type checker (compiling vs throwing an "Ambiguous use of..." error).
Should I report a bug here or am I missing something?

On Tue, Feb 28, 2017 at 9:35 AM, Matthew Johnson 
wrote:

>
> On Feb 28, 2017, at 11:33 AM, Joe Groff  wrote:
>
>
> On Feb 28, 2017, at 9:23 AM, Matthew Johnson 
> wrote:
>
>
> On Feb 28, 2017, at 11:04 AM, Joe Groff via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Feb 27, 2017, at 4:34 PM, Rex Fenley via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> I often find myself running into situations where I'll receive "Ambiguous
> use of..." for overloaded functions or operators. In every case these
> situations would be easily solved if I could specify "Generic !=
> CertainType" in the where clause of one of the overloads so I can
> disambiguate the cases. Could this be added to language?
>
>
> Do you have a concrete example where you need this? It'd be good to know
> whether the types are ambiguous due to type checker bugs, or whether
> there's a principle by which they could be naturally ordered. Instead of
> overloading, can you do the type test via `if !(x is CertainType)` within a
> single implementation?
>
>
> The best use case I can think of is if we had enum cases where the
> associated value is a subtype of the enum:
>
> enum Result where E: Error, T != E {
>   case some(T) -> T
>   case error(E) -> E
> }
>
>
> I don't think that's a good design for that type. I can see the desire for
> a subtype relationship between T and Result, but no good reason for
> the error to also be a subtype. That != constraint would have to be
> propagated through anything using `Result` as well.
>
>
> Ok, just change it to a fully generic Either type then.  I’m not arguing
> for or against this constraint, just pointing out a use case that is
> enabled by it.  It’s reasonable to argue that we don’t want to support this
> use case.
>
>
> -Joe
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] 'T != Type' in where clause

2017-02-27 Thread Rex Fenley via swift-evolution
I often find myself running into situations where I'll receive "Ambiguous
use of..." for overloaded functions or operators. In every case these
situations would be easily solved if I could specify "Generic !=
CertainType" in the where clause of one of the overloads so I can
disambiguate the cases. Could this be added to language?

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


[swift-evolution] Recursive protocol constraints

2017-02-07 Thread Rex Fenley via swift-evolution
Does "Permit where clauses to constrain associated types" (
https://github.com/apple/swift-evolution/blob/master/proposals/0142-associated-types-constraints.md)
also
include "Recursive protocol constraints"? The "Motivation" section seems to
imply this. If not, will this be making it into Swift 4?

Thanks!

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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


Re: [swift-evolution] Either protocol syntax

2017-02-02 Thread Rex Fenley via swift-evolution
But then any time as user of the pipeline I'm writing would like a new type
of collection they will be forced to inherit this new protocol vs one
they're already familiar with and which the collection may already conform
too.

On Thu, Feb 2, 2017 at 1:53 PM, Matthew Johnson 
wrote:

>
> On Feb 2, 2017, at 3:46 PM, Rex Fenley  wrote:
>
> My use case is RLMArray and it can't implement RangeReplaceableCollection 
> though
> because `init` is unavailable, additionally, there's a lot of parts to the
> protocol that would take some time to implement correctly if I could. They
> offer a Swift type List that wraps RLMArray and does a bunch of stuff to
> implement RangeReplaceableCollection, but they discourage using their
> Swift library in mixed Obj-C/Swift projects and certain model objects
> simply couldn't use the List type anyway because they're also used in Obj-C
> and List is not @objc compliant.
>
> So this leaves me in situations where when I need to use Array or RLMArray
> I have to duplicate my code, not just in one place, but all the way down a
> pipeline in order to have my generics work with either
> RangeReplaceableCollection or RLMArray.
>
> If I could abstract the commonalities required by my application, I could
> just have a RLMArrayProtocol that has RLMArray's exposed function
> signatures and a new protocol Appendable = RangeReplaceableCollection | 
> RLMArrayProtocol
> and this will type check all the way through the pipeline.
>
> tl;dr - if a function signature required by a protocol is marked
> unavailable on a class, then disjunction is necessary in order to bridge
> the two (or more) types without duplicating code.
>
>
> You should be able to solve this problem today by creating a custom
> protocol that you use as a constraint in your generic code and providing
> conformances for both Array and RLMArray.
>
>
> On Thu, Feb 2, 2017 at 1:35 PM, Matthew Johnson 
> wrote:
>
>>
>> On Feb 2, 2017, at 3:26 PM, Rex Fenley via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hello, I believe there was some discussion about this quite awhile ago. I
>> was wondering if there's any interest in including a protocol 'or' type
>> that would be the intersection of two protocols. This could be really
>> useful in situations where a framework that the user has no control over
>> implements a portion of some often used protocol. Such as specialized
>> collections from an Database framework that don't implement
>> RangeReplaceableCollection but have a set of methods that are equivalent.
>> The user can then implement a protocol that is the intersection of those
>> set of methods and not duplicate code.
>>
>>
>> If the specialized collection in the database framework already provides
>> functionality equivalent to `RangeReplaceableCollection` what you really
>> want to do is just provide the conformance you’re looking for in an
>> extension:
>>
>> extension SpecializedDatabaseCollection: RangeReplaceableCollection {
>>// if necessary, provide forwarding wrappers where the member names
>> don’t match up.
>> }
>>
>> But in a case like this the framework itself really should provide this
>> conformance out of the box.  If they didn’t, maybe there is a good reason
>> so you would want to find out why it wasn’t provided.
>>
>> Is there something you’re hoping to do that you can’t solve by simply
>> extending the framework types?
>>
>>
>> Simplified example:
>>
>> protocol Animal {
>> var hasEars: Bool { get }
>> func grow()
>> }
>>
>> protocol Plant {
>> var isGreen: Bool { get }
>> func grow()
>> }
>>
>> protocol LivingThing = Plant | Animal // or a different syntax
>>
>> LivingThing's is as follows
>> {
>> func grow()
>> }
>>
>>
>> --
>> Rex Fenley  |  IOS DEVELOPER
>>
>> Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
>>  |  FOLLOW US <https://twitter.com/remindhq>  |  LIKE US
>> <https://www.facebook.com/remindhq>
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>
>>
>>
>
>
> --
> Rex Fenley  |  IOS DEVELOPER
>
> Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>  |
>  FOLLOW US <https://twitter.com/remindhq>  |  LIKE US
> <https://www.facebook.com/remindhq>
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Either protocol syntax

2017-02-02 Thread Rex Fenley via swift-evolution
My use case is RLMArray and it can't implement
RangeReplaceableCollection though
because `init` is unavailable, additionally, there's a lot of parts to the
protocol that would take some time to implement correctly if I could. They
offer a Swift type List that wraps RLMArray and does a bunch of stuff to
implement RangeReplaceableCollection, but they discourage using their Swift
library in mixed Obj-C/Swift projects and certain model objects simply
couldn't use the List type anyway because they're also used in Obj-C and
List is not @objc compliant.

So this leaves me in situations where when I need to use Array or RLMArray
I have to duplicate my code, not just in one place, but all the way down a
pipeline in order to have my generics work with either
RangeReplaceableCollection
or RLMArray.

If I could abstract the commonalities required by my application, I could
just have a RLMArrayProtocol that has RLMArray's exposed function
signatures and a new protocol Appendable = RangeReplaceableCollection
| RLMArrayProtocol
and this will type check all the way through the pipeline.

tl;dr - if a function signature required by a protocol is marked
unavailable on a class, then disjunction is necessary in order to bridge
the two (or more) types without duplicating code.

On Thu, Feb 2, 2017 at 1:35 PM, Matthew Johnson 
wrote:

>
> On Feb 2, 2017, at 3:26 PM, Rex Fenley via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hello, I believe there was some discussion about this quite awhile ago. I
> was wondering if there's any interest in including a protocol 'or' type
> that would be the intersection of two protocols. This could be really
> useful in situations where a framework that the user has no control over
> implements a portion of some often used protocol. Such as specialized
> collections from an Database framework that don't implement
> RangeReplaceableCollection but have a set of methods that are equivalent.
> The user can then implement a protocol that is the intersection of those
> set of methods and not duplicate code.
>
>
> If the specialized collection in the database framework already provides
> functionality equivalent to `RangeReplaceableCollection` what you really
> want to do is just provide the conformance you’re looking for in an
> extension:
>
> extension SpecializedDatabaseCollection: RangeReplaceableCollection {
>// if necessary, provide forwarding wrappers where the member names
> don’t match up.
> }
>
> But in a case like this the framework itself really should provide this
> conformance out of the box.  If they didn’t, maybe there is a good reason
> so you would want to find out why it wasn’t provided.
>
> Is there something you’re hoping to do that you can’t solve by simply
> extending the framework types?
>
>
> Simplified example:
>
> protocol Animal {
> var hasEars: Bool { get }
> func grow()
> }
>
> protocol Plant {
> var isGreen: Bool { get }
> func grow()
> }
>
> protocol LivingThing = Plant | Animal // or a different syntax
>
> LivingThing's is as follows
> {
> func grow()
> }
>
>
> --
> Rex Fenley  |  IOS DEVELOPER
>
> Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>  |
>  FOLLOW US <https://twitter.com/remindhq>  |  LIKE US
> <https://www.facebook.com/remindhq>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
>
>


-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com <https://www.remind.com/> |  BLOG <http://blog.remind.com/>
 |  FOLLOW
US <https://twitter.com/remindhq>  |  LIKE US
<https://www.facebook.com/remindhq>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Either protocol syntax

2017-02-02 Thread Rex Fenley via swift-evolution
Hello, I believe there was some discussion about this quite awhile ago. I
was wondering if there's any interest in including a protocol 'or' type
that would be the intersection of two protocols. This could be really
useful in situations where a framework that the user has no control over
implements a portion of some often used protocol. Such as specialized
collections from an Database framework that don't implement
RangeReplaceableCollection but have a set of methods that are equivalent.
The user can then implement a protocol that is the intersection of those
set of methods and not duplicate code.

Simplified example:

protocol Animal {
var hasEars: Bool { get }
func grow()
}

protocol Plant {
var isGreen: Bool { get }
func grow()
}

protocol LivingThing = Plant | Animal // or a different syntax

LivingThing's is as follows
{
func grow()
}

-- 

Rex Fenley  |  IOS DEVELOPER

Remind.com  |  BLOG 
 |  FOLLOW
US   |  LIKE US

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