Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Jānis Kiršteins via swift-evolution
I think you misunderstood my proposed syntax. To clarify:

enum Suit {
let bezierPath: UIBezierPath // Stored property declaration

case spades {
let bezierPath = UIBezierPath() // Declare and initialize and
local variable, this is not stored property declaration
// add drawing commands to bezierPath
self.bezierPath = bezierPath // Initialize stored property
with local variable. Stored property is shared among cases
}
}


I agree that cases should not be treated as pseudo-type, I am not
proposing that. What I am proposing is the that enum instance
behaviour and data can be very dependent of it case. And that there
should be easier and clearer ways to configure that using stored
properties.


On Thu, Jun 2, 2016 at 10:26 AM, Brent Royal-Gordon
 wrote:
>> As stated before it supposed to be per case initialization. You cannot
>> really have this analogy with other types as they have type and
>> instance while enums have type, case and instance.
>
> No. If structs have just type and instance, then so do enums.
>
> Cases in enums are analogous to stored properties in structs: they are a 
> means of organizing and representing concrete storage. They are not 
> first-class entities in the way that types and instances are. Much mischief 
> comes from thinking of cases as pseudo-types, or as some sort of peer to a 
> type.
>
>> But consider this:
>>
>> struct Struct {
>>static let bezierPath: UIBezierPath // shared
>>
>>static func initialize() {
>>bezierPath = UIBezierPath()
>>}
>> }
>
> Yes, because there's a `static` keyword on that declaration. That marks it as 
> something different from an ordinary `let`. Similarly, part of the idea of my 
> use of accessors is that the `accessor` keyword marks it as something 
> different from an ordinary `var`.
>
> (Also, you shouldn't use `initialize()` in Swift; you should set the variable 
> directly. Also also, I'm pretty sure that wouldn't work at all, because 
> `initialize()` is a normal method, not an initializer, and `bezierPath` is a 
> constant.)
>
> --
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Brent Royal-Gordon via swift-evolution
> As stated before it supposed to be per case initialization. You cannot
> really have this analogy with other types as they have type and
> instance while enums have type, case and instance.

No. If structs have just type and instance, then so do enums.

Cases in enums are analogous to stored properties in structs: they are a means 
of organizing and representing concrete storage. They are not first-class 
entities in the way that types and instances are. Much mischief comes from 
thinking of cases as pseudo-types, or as some sort of peer to a type.

> But consider this:
> 
> struct Struct {
>static let bezierPath: UIBezierPath // shared
> 
>static func initialize() {
>bezierPath = UIBezierPath()
>}
> }

Yes, because there's a `static` keyword on that declaration. That marks it as 
something different from an ordinary `let`. Similarly, part of the idea of my 
use of accessors is that the `accessor` keyword marks it as something different 
from an ordinary `var`.

(Also, you shouldn't use `initialize()` in Swift; you should set the variable 
directly. Also also, I'm pretty sure that wouldn't work at all, because 
`initialize()` is a normal method, not an initializer, and `bezierPath` is a 
constant.)

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-02 Thread Jānis Kiršteins via swift-evolution
As stated before it supposed to be per case initialization. You cannot
really have this analogy with other types as they have type and
instance while enums have type, case and instance. But consider this:

struct Struct {
static let bezierPath: UIBezierPath // shared

static func initialize() {
bezierPath = UIBezierPath()
}
}

On Thu, Jun 2, 2016 at 12:18 AM, Brent Royal-Gordon
 wrote:
>> UIBezierPath is shared for all instances of the enum case. So stored
>> properties are stored per case, not per instance (you have associated
>> values for per instance values).
>>
>>> that isn't really what this syntax suggests is happening
>>
>> Please explain what makes you think that way.
>
> Because you wrote `let bezierPath = UIBezierPath()` in the middle of a type 
> definition, and in all other types, you would get a new bezier path for each 
> instance.
>
> struct Struct {
> let bezierPath = UIBezierPath() // per instance
> }
> class Class {
> let bezierPath = UIBezierPath() // per instance
> }
> func function() {
> let bezierPath = UIBezierPath() // per call
> }
> enum Enum {
> case aCase {
> let bezierPath = UIBezierPath() // shared?!?!
> }
> }
>
> --
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Brent Royal-Gordon via swift-evolution
> UIBezierPath is shared for all instances of the enum case. So stored
> properties are stored per case, not per instance (you have associated
> values for per instance values).
> 
>> that isn't really what this syntax suggests is happening
> 
> Please explain what makes you think that way.

Because you wrote `let bezierPath = UIBezierPath()` in the middle of a type 
definition, and in all other types, you would get a new bezier path for each 
instance.

struct Struct {
let bezierPath = UIBezierPath() // per instance
}
class Class {
let bezierPath = UIBezierPath() // per instance
}
func function() {
let bezierPath = UIBezierPath() // per call
}
enum Enum {
case aCase {
let bezierPath = UIBezierPath() // shared?!?!
}
}

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Goffredo Marocchi via swift-evolution
Hello David,

Could you elaborate on this more? Seeing the possibilities of FSM's in
Swift using its powerful enum and case pattern matching was one of the
moments in which Swift started increasing its allure factor ;).

Part 1 (background and theory):
http://www.figure.ink/blog/2015/1/31/swift-state-machines-part-1

Part 2 (start of the implementation):
http://www.figure.ink/blog/2015/2/1/swift-state-machines-part-2

Part 3:
http://www.figure.ink/blog/2015/2/8/swift-state-machines-part-3-follow-up

Part 4:
http://www.figure.ink/blog/2015/2/9/swift-state-machines-part-4-redirect



Final gist: https://gist.github.com/jemmons/f30f1de292751da0f1b7


On Wed, Jun 1, 2016 at 3:48 PM, David Waite via swift-evolution <
swift-evolution@swift.org> wrote:

> One thing I did often in Java (and miss in Swift) is using their enums to
> build state machines or implement command patterns for common commands.
>
> Java enums are a sealed set of subclasses of the enum base type with
> (hopefully) immutable, singleton instances. So you can do fun things like:
> - Define the base class constructor to be called to instantiate the
> subclasses, and declare the cases with the constructor arguments
> - Declare a method on the base type and refine it on 1-2 particular cases
> - Declare the enum implements an interface, and implement that interface
> separately for each case.
> - Define data accessors specific to the type (such as the planets example
> above)
>
> I like the SuitInfo approach below - with extensions, I think I can get
> close to what I have done in the past with Java. Maybe one day there is
> syntax to do this in the language directly
>
> -DW
>
> > On May 31, 2016, at 11:44 AM, Vladimir.S via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > I'm not sure about my opinion on this proposal, but I believe you should
> add this as alternatives of how we can have the similar features today
> without injecting stored properties into enums  :
> >
> > enum Suit {
> >case spades
> >case hearts
> >case diamonds
> >case clubs
> >
> >struct SuitInfo {
> >let simpleDescription: String
> >let color: UIColor
> >let symbol: String
> >let bezierPath: UIBezierPath
> >}
> >
> >var info : SuitInfo {
> >switch self {
> >case .spades:
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "spades",
> >color: .blackColor(),
> >symbol: "♠",
> >bezierPath: path)
> >
> >case .hearts:
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "hearts",
> >color: .redColor(),
> >symbol: "♥",
> >bezierPath: path)
> >
> >case .diamonds:
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "diamonds",
> >color: .redColor(),
> >symbol: "♦",
> >bezierPath: path)
> >
> >case .clubs:
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "clubs",
> >color: .blackColor(),
> >symbol: "♣",
> >bezierPath: path)
> >
> >}
> >}
> > }
> >
> > and this:
> >
> > enum Suit  {
> >case spades
> >case hearts
> >case diamonds
> >case clubs
> >
> >struct SuitInfo  {
> >let simpleDescription: String
> >let color: UIColor
> >let symbol: String
> >let bezierPath: UIBezierPath
> >}
> >
> >static let spadesInfo : SuitInfo = {
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "spades",
> >color: .blackColor(),
> >symbol: "♠",
> >bezierPath: path)
> >}()
> >
> >static let heartsInfo : SuitInfo = {
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "hearts",
> >color: .redColor(),
> >symbol: "♥",
> >bezierPath: path)
> >}()
> >
> >static let diamondsInfo : SuitInfo = {
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "diamonds",
> >color: .redColor(),
> >symbol: "♦",
> >bezierPath: path)
> >}()
> >
> >static let clubsInfo : SuitInfo = {
> >let path = UIBezierPath()
> >// omitted lines ...
> >
> >return SuitInfo(
> >simpleDescription: "clubs",
> >color: .blackColor(),
> >symbol: "♣",
> >  

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Leonardo Pessoa via swift-evolution
I'm not much fond of Java enums but then Java also doesn't have
structs so I think enums there were created to be a mix of structs and
enums and that's why you can do all the things you mention on your
list. That said:
- The tuple typed enum approach is the closest thing we discussed to
constructors like the ones in Java enums;
- I never knew one could do that in Java but I think tuples can hold
function types;
- I also never heard one can do that in Java but I begin to think what
you really want are structs here;
- Both approaches here provide that, but accessors would allow for
dynamic content to be generated, not static.

Also Swift already allow for functions to be declared in enums and I
think this would be a better place than accessor properties to place
code that will generate dynamic results.

L

On 1 June 2016 at 11:59, Matthew Johnson via swift-evolution
 wrote:
>
>
> Sent from my iPad
>
>> On Jun 1, 2016, at 9:48 AM, David Waite via swift-evolution 
>>  wrote:
>>
>> One thing I did often in Java (and miss in Swift) is using their enums to 
>> build state machines or implement command patterns for common commands.
>>
>> Java enums are a sealed set of subclasses of the enum base type with 
>> (hopefully) immutable, singleton instances. So you can do fun things like:
>> - Define the base class constructor to be called to instantiate the 
>> subclasses, and declare the cases with the constructor arguments
>> - Declare a method on the base type and refine it on 1-2 particular cases
>> - Declare the enum implements an interface, and implement that interface 
>> separately for each case.
>> - Define data accessors specific to the type (such as the planets example 
>> above)
>>
>> I like the SuitInfo approach below - with extensions, I think I can get 
>> close to what I have done in the past with Java. Maybe one day there is 
>> syntax to do this in the language directly
>
> This is pretty similar to what we were discussing last week in this thread: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/018799.html
>
> I'm planning to write up a proposal when I have time (hopefully in the next 
> week or so).
>
>>
>> -DW
>>
>>> On May 31, 2016, at 11:44 AM, Vladimir.S via swift-evolution 
>>>  wrote:
>>>
>>> I'm not sure about my opinion on this proposal, but I believe you should 
>>> add this as alternatives of how we can have the similar features today 
>>> without injecting stored properties into enums  :
>>>
>>> enum Suit {
>>>   case spades
>>>   case hearts
>>>   case diamonds
>>>   case clubs
>>>
>>>   struct SuitInfo {
>>>   let simpleDescription: String
>>>   let color: UIColor
>>>   let symbol: String
>>>   let bezierPath: UIBezierPath
>>>   }
>>>
>>>   var info : SuitInfo {
>>>   switch self {
>>>   case .spades:
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "spades",
>>>   color: .blackColor(),
>>>   symbol: "♠",
>>>   bezierPath: path)
>>>
>>>   case .hearts:
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "hearts",
>>>   color: .redColor(),
>>>   symbol: "♥",
>>>   bezierPath: path)
>>>
>>>   case .diamonds:
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "diamonds",
>>>   color: .redColor(),
>>>   symbol: "♦",
>>>   bezierPath: path)
>>>
>>>   case .clubs:
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "clubs",
>>>   color: .blackColor(),
>>>   symbol: "♣",
>>>   bezierPath: path)
>>>
>>>   }
>>>   }
>>> }
>>>
>>> and this:
>>>
>>> enum Suit  {
>>>   case spades
>>>   case hearts
>>>   case diamonds
>>>   case clubs
>>>
>>>   struct SuitInfo  {
>>>   let simpleDescription: String
>>>   let color: UIColor
>>>   let symbol: String
>>>   let bezierPath: UIBezierPath
>>>   }
>>>
>>>   static let spadesInfo : SuitInfo = {
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "spades",
>>>   color: .blackColor(),
>>>   symbol: "♠",
>>>   bezierPath: path)
>>>   }()
>>>
>>>   static let heartsInfo : SuitInfo = {
>>>   let path = UIBezierPath()
>>>   // omitted lines ...
>>>
>>>   return SuitInfo(
>>>   simpleDescription: "hearts",
>>>   color: .redColor(),
>>>   symbol: "♥",
>>>   bezierPath: path)
>>>   }()
>>>
>>>   static let diamondsInfo : SuitInfo = {
>>>   

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Paul Cantrell via swift-evolution

> On Jun 1, 2016, at 9:48 AM, David Waite via swift-evolution 
>  wrote:
> 
> One thing I did often in Java (and miss in Swift) is using their enums to 
> build state machines or implement command patterns for common commands.
> 
> Java enums are a sealed set of subclasses of the enum base type with 
> (hopefully) immutable, singleton instances. So you can do fun things like:
> - Define the base class constructor to be called to instantiate the 
> subclasses, and declare the cases with the constructor arguments
> - Declare a method on the base type and refine it on 1-2 particular cases
> - Declare the enum implements an interface, and implement that interface 
> separately for each case.
> - Define data accessors specific to the type (such as the planets example 
> above)

+1 to this behavior — one of the increasingly rare places where Java is nicer 
than Swift. This is the natural generalization / next step of the stored 
properties of this thread, and I can confirm what David said: it’s useful in 
practice.

P

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Jun 1, 2016, at 9:48 AM, David Waite via swift-evolution 
>  wrote:
> 
> One thing I did often in Java (and miss in Swift) is using their enums to 
> build state machines or implement command patterns for common commands.
> 
> Java enums are a sealed set of subclasses of the enum base type with 
> (hopefully) immutable, singleton instances. So you can do fun things like:
> - Define the base class constructor to be called to instantiate the 
> subclasses, and declare the cases with the constructor arguments
> - Declare a method on the base type and refine it on 1-2 particular cases
> - Declare the enum implements an interface, and implement that interface 
> separately for each case.
> - Define data accessors specific to the type (such as the planets example 
> above)
> 
> I like the SuitInfo approach below - with extensions, I think I can get close 
> to what I have done in the past with Java. Maybe one day there is syntax to 
> do this in the language directly

This is pretty similar to what we were discussing last week in this thread: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160523/018799.html

I'm planning to write up a proposal when I have time (hopefully in the next 
week or so).

> 
> -DW
> 
>> On May 31, 2016, at 11:44 AM, Vladimir.S via swift-evolution 
>>  wrote:
>> 
>> I'm not sure about my opinion on this proposal, but I believe you should add 
>> this as alternatives of how we can have the similar features today without 
>> injecting stored properties into enums  :
>> 
>> enum Suit {
>>   case spades
>>   case hearts
>>   case diamonds
>>   case clubs
>> 
>>   struct SuitInfo {
>>   let simpleDescription: String
>>   let color: UIColor
>>   let symbol: String
>>   let bezierPath: UIBezierPath
>>   }
>> 
>>   var info : SuitInfo {
>>   switch self {
>>   case .spades:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "spades",
>>   color: .blackColor(),
>>   symbol: "♠",
>>   bezierPath: path)
>> 
>>   case .hearts:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "hearts",
>>   color: .redColor(),
>>   symbol: "♥",
>>   bezierPath: path)
>> 
>>   case .diamonds:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "diamonds",
>>   color: .redColor(),
>>   symbol: "♦",
>>   bezierPath: path)
>> 
>>   case .clubs:
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "clubs",
>>   color: .blackColor(),
>>   symbol: "♣",
>>   bezierPath: path)
>> 
>>   }
>>   }
>> }
>> 
>> and this:
>> 
>> enum Suit  {
>>   case spades
>>   case hearts
>>   case diamonds
>>   case clubs
>> 
>>   struct SuitInfo  {
>>   let simpleDescription: String
>>   let color: UIColor
>>   let symbol: String
>>   let bezierPath: UIBezierPath
>>   }
>> 
>>   static let spadesInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "spades",
>>   color: .blackColor(),
>>   symbol: "♠",
>>   bezierPath: path)
>>   }()
>> 
>>   static let heartsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "hearts",
>>   color: .redColor(),
>>   symbol: "♥",
>>   bezierPath: path)
>>   }()
>> 
>>   static let diamondsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "diamonds",
>>   color: .redColor(),
>>   symbol: "♦",
>>   bezierPath: path)
>>   }()
>> 
>>   static let clubsInfo : SuitInfo = {
>>   let path = UIBezierPath()
>>   // omitted lines ...
>> 
>>   return SuitInfo(
>>   simpleDescription: "clubs",
>>   color: .blackColor(),
>>   symbol: "♣",
>>   bezierPath: path)
>>   }()
>> 
>> 
>>   var info : SuitInfo {
>>   switch self {
>>   case .spades: return Suit.spadesInfo
>>   case .hearts: return Suit.heartsInfo
>>   case .diamonds: return Suit.diamondsInfo
>>   case .clubs: return Suit.clubsInfo
>>   }
>>   }
>> }
>> 
>> 
>>> On 31.05.2016 17:17, Jānis Kiršteins via swift-evolution wrote:
>>> I wrote a proposal draft:
>>> 
>>> # Enum case stored properties
>>> 
>>> * Proposal: TBD
>>> * Author: [Janis Kirsteins](https://github.com/kirsteins)
>>> 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread David Waite via swift-evolution
One thing I did often in Java (and miss in Swift) is using their enums to build 
state machines or implement command patterns for common commands.

Java enums are a sealed set of subclasses of the enum base type with 
(hopefully) immutable, singleton instances. So you can do fun things like:
- Define the base class constructor to be called to instantiate the subclasses, 
and declare the cases with the constructor arguments
- Declare a method on the base type and refine it on 1-2 particular cases
- Declare the enum implements an interface, and implement that interface 
separately for each case.
- Define data accessors specific to the type (such as the planets example above)

I like the SuitInfo approach below - with extensions, I think I can get close 
to what I have done in the past with Java. Maybe one day there is syntax to do 
this in the language directly

-DW

> On May 31, 2016, at 11:44 AM, Vladimir.S via swift-evolution 
>  wrote:
> 
> I'm not sure about my opinion on this proposal, but I believe you should add 
> this as alternatives of how we can have the similar features today without 
> injecting stored properties into enums  :
> 
> enum Suit {
>case spades
>case hearts
>case diamonds
>case clubs
> 
>struct SuitInfo {
>let simpleDescription: String
>let color: UIColor
>let symbol: String
>let bezierPath: UIBezierPath
>}
> 
>var info : SuitInfo {
>switch self {
>case .spades:
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "spades",
>color: .blackColor(),
>symbol: "♠",
>bezierPath: path)
> 
>case .hearts:
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "hearts",
>color: .redColor(),
>symbol: "♥",
>bezierPath: path)
> 
>case .diamonds:
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "diamonds",
>color: .redColor(),
>symbol: "♦",
>bezierPath: path)
> 
>case .clubs:
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "clubs",
>color: .blackColor(),
>symbol: "♣",
>bezierPath: path)
> 
>}
>}
> }
> 
> and this:
> 
> enum Suit  {
>case spades
>case hearts
>case diamonds
>case clubs
> 
>struct SuitInfo  {
>let simpleDescription: String
>let color: UIColor
>let symbol: String
>let bezierPath: UIBezierPath
>}
> 
>static let spadesInfo : SuitInfo = {
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "spades",
>color: .blackColor(),
>symbol: "♠",
>bezierPath: path)
>}()
> 
>static let heartsInfo : SuitInfo = {
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "hearts",
>color: .redColor(),
>symbol: "♥",
>bezierPath: path)
>}()
> 
>static let diamondsInfo : SuitInfo = {
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "diamonds",
>color: .redColor(),
>symbol: "♦",
>bezierPath: path)
>}()
> 
>static let clubsInfo : SuitInfo = {
>let path = UIBezierPath()
>// omitted lines ...
> 
>return SuitInfo(
>simpleDescription: "clubs",
>color: .blackColor(),
>symbol: "♣",
>bezierPath: path)
>}()
> 
> 
>var info : SuitInfo {
>switch self {
>case .spades: return Suit.spadesInfo
>case .hearts: return Suit.heartsInfo
>case .diamonds: return Suit.diamondsInfo
>case .clubs: return Suit.clubsInfo
>}
>}
> }
> 
> 
> On 31.05.2016 17:17, Jānis Kiršteins via swift-evolution wrote:
>> I wrote a proposal draft:
>> 
>> # Enum case stored properties
>> 
>> * Proposal: TBD
>> * Author: [Janis Kirsteins](https://github.com/kirsteins)
>> * Status: TBD
>> * Review manager: TBD
>> 
>> ## Introduction
>> 
>> This proposal allows each enum case to have stored properties.
>> 
>> ## Motivation
>> 
>> Enums cases can have a lot of constant (or variable) static values
>> associated with it. For example, planets can have mass, radius, age,
>> closest star etc. Currently there is no way to set or get those values
>> easily.
>> 
>> Example below shows that is hard to read and manage static associated

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-06-01 Thread Jānis Kiršteins via swift-evolution
UIBezierPath is shared for all instances of the enum case. So stored
properties are stored per case, not per instance (you have associated
values for per instance values).

> that isn't really what this syntax suggests is happening

Please explain what makes you think that way.


On Tue, May 31, 2016 at 11:52 PM, Brent Royal-Gordon
 wrote:
>>case spades {
> 
>>let bezierPath = UIBezierPath()
>
> Does each instance of `.spades` have a *separate* UIBezierPath, or do all 
> instances of `.spades` share one? If it's the former, I have strong doubts 
> you'll actually get this through. If it's the latter, that isn't really what 
> this syntax suggests is happening.
>
> --
> Brent Royal-Gordon
> Architechies
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-31 Thread Brent Royal-Gordon via swift-evolution
>case spades {

>let bezierPath = UIBezierPath()

Does each instance of `.spades` have a *separate* UIBezierPath, or do all 
instances of `.spades` share one? If it's the former, I have strong doubts 
you'll actually get this through. If it's the latter, that isn't really what 
this syntax suggests is happening.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-31 Thread Charles Srstka via swift-evolution
A huge +1 on the syntax change, which I think is a colossal improvement over 
the current situation and adds a lot of clarity to enum declarations.

Neutral on the necessity to add actual stored properties to the enums. If the 
new syntax were merely syntactic sugar that would effectively generate the 
switch statements behind the scenes, that would work for me too, and would 
probably offend fewer people.

Charles

> On May 31, 2016, at 9:17 AM, Jānis Kiršteins via swift-evolution 
>  wrote:
> 
> I wrote a proposal draft:
> 
> # Enum case stored properties
> 
> * Proposal: TBD
> * Author: [Janis Kirsteins](https://github.com/kirsteins)
> * Status: TBD
> * Review manager: TBD
> 
> ## Introduction
> 
> This proposal allows each enum case to have stored properties.
> 
> ## Motivation
> 
> Enums cases can have a lot of constant (or variable) static values
> associated with it. For example, planets can have mass, radius, age,
> closest star etc. Currently there is no way to set or get those values
> easily.
> 
> Example below shows that is hard to read and manage static associated
> values with each case. It is hard to add or remove case as it would
> require to add or remove code in four different places in file. Also
> static associated value like `UIBezierPath` is recreated each time the
> property is computed while it's constant.
> 
> ```swift
> enum Suit {
>case spades
>case hearts
>case diamonds
>case clubs
> 
>var simpleDescription: String {
>switch self {
>case .spades:
>return "spades"
>case .hearts:
>return "hearts"
>case .diamonds:
>return "diamonds"
>case .clubs:
>return "clubs"
>}
>}
> 
>var color: UIColor {
>switch self {
>case .spades:
>return .blackColor()
>case .hearts:
>return .redColor()
>case .diamonds:
>return .redColor()
>case .clubs:
>return .blackColor()
>}
>}
> 
>var symbol: String {
>switch self {
>case .spades:
>return "♠"
>case .hearts:
>return "♥"
>case .diamonds:
>return "♦"
>case .clubs:
>return "♣"
>}
>}
> 
>var bezierPath: UIBezierPath {
>switch self {
>case .spades:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .hearts:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .diamonds:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>case .clubs:
>let path = UIBezierPath()
>// omitted lines ...
>return path
>}
>}
> }
> ```
> 
> ## Proposed solution
> 
> Support stored properties for enum cases just as each case were an
> instance. Case properties are initialized block after each case
> declaration.
> 
> ```swift
> enum Suit {
>let simpleDescription: String
>let color: UIColor
>let symbol: String
>let bezierPath: UIBezierPath
> 
>case spades {
>simpleDescription = "spades"
>color = .blackColor()
>symbol = "♠"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case hearts {
>simpleDescription = "hearts"
>color = .redColor()
>symbol = "♥"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case diamonds {
>simpleDescription = "diamonds"
>color = .redColor()
>symbol = "♦"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> 
>case clubs {
>simpleDescription = "clubs"
>color = .blackColor()
>symbol = "♣"
>let bezierPath = UIBezierPath()
>// omitted lines ...
>self.bezierPath = bezierPath
>}
> }
> 
> let symbol = Suit.spades.symbol // "♠"
> ```
> 
> The proposed solution improves:
> - Readability as cases are closer with their related data;
> - Improves code maintainability as a case can be removed or added in one 
> place;
> - Improved performance as there is no need to recreate static values;
> - ~30% less lines of code in given example.
> 
> ## Detailed design
> 
>  Stored properties
> 
> Enum stored properties are supported the same way they are supported
> for structs can classes. Unlike enum associated values, stored
> properties are static to case and are shared for the same case.
> 
> Properties are accessed:
> ```swift
> let simpleDescription = Suit.spades.simpleDescription
> ```
> 
> Mutable properties can be set:
> ```swift
> Suit.spades.simpleDescription = "new simple description"
> ```
> 
>  Initialization
> 
> If enum 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-31 Thread Vladimir.S via swift-evolution
I'm not sure about my opinion on this proposal, but I believe you should 
add this as alternatives of how we can have the similar features today 
without injecting stored properties into enums  :


enum Suit {
case spades
case hearts
case diamonds
case clubs

struct SuitInfo {
let simpleDescription: String
let color: UIColor
let symbol: String
let bezierPath: UIBezierPath
}

var info : SuitInfo {
switch self {
case .spades:
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "spades",
color: .blackColor(),
symbol: "♠",
bezierPath: path)

case .hearts:
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "hearts",
color: .redColor(),
symbol: "♥",
bezierPath: path)

case .diamonds:
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "diamonds",
color: .redColor(),
symbol: "♦",
bezierPath: path)

case .clubs:
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "clubs",
color: .blackColor(),
symbol: "♣",
bezierPath: path)

}
}
}

and this:

enum Suit  {
case spades
case hearts
case diamonds
case clubs

struct SuitInfo  {
let simpleDescription: String
let color: UIColor
let symbol: String
let bezierPath: UIBezierPath
}

static let spadesInfo : SuitInfo = {
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "spades",
color: .blackColor(),
symbol: "♠",
bezierPath: path)
}()

static let heartsInfo : SuitInfo = {
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "hearts",
color: .redColor(),
symbol: "♥",
bezierPath: path)
}()

static let diamondsInfo : SuitInfo = {
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "diamonds",
color: .redColor(),
symbol: "♦",
bezierPath: path)
}()

static let clubsInfo : SuitInfo = {
let path = UIBezierPath()
// omitted lines ...

return SuitInfo(
simpleDescription: "clubs",
color: .blackColor(),
symbol: "♣",
bezierPath: path)
}()


var info : SuitInfo {
switch self {
case .spades: return Suit.spadesInfo
case .hearts: return Suit.heartsInfo
case .diamonds: return Suit.diamondsInfo
case .clubs: return Suit.clubsInfo
}
}
}


On 31.05.2016 17:17, Jānis Kiršteins via swift-evolution wrote:

I wrote a proposal draft:

# Enum case stored properties

* Proposal: TBD
* Author: [Janis Kirsteins](https://github.com/kirsteins)
* Status: TBD
* Review manager: TBD

## Introduction

This proposal allows each enum case to have stored properties.

## Motivation

Enums cases can have a lot of constant (or variable) static values
associated with it. For example, planets can have mass, radius, age,
closest star etc. Currently there is no way to set or get those values
easily.

Example below shows that is hard to read and manage static associated
values with each case. It is hard to add or remove case as it would
require to add or remove code in four different places in file. Also
static associated value like `UIBezierPath` is recreated each time the
property is computed while it's constant.

```swift
enum Suit {
case spades
case hearts
case diamonds
case clubs

var simpleDescription: String {
switch self {
case .spades:
return "spades"
case .hearts:
return "hearts"
case .diamonds:
return "diamonds"
case .clubs:
return "clubs"
}
}

var color: UIColor {
switch self {
case .spades:
return .blackColor()
case .hearts:
return .redColor()
case .diamonds:
return .redColor()
case .clubs:
return .blackColor()
}
}

var symbol: String {
switch self {
case .spades:
return "♠"
case .hearts:
return "♥"
case .diamonds:
return "♦"
case .clubs:
return "♣"
}
}

var bezierPath: UIBezierPath {
switch self {
case 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-31 Thread Jānis Kiršteins via swift-evolution
I wrote a proposal draft:

# Enum case stored properties

* Proposal: TBD
* Author: [Janis Kirsteins](https://github.com/kirsteins)
* Status: TBD
* Review manager: TBD

## Introduction

This proposal allows each enum case to have stored properties.

## Motivation

Enums cases can have a lot of constant (or variable) static values
associated with it. For example, planets can have mass, radius, age,
closest star etc. Currently there is no way to set or get those values
easily.

Example below shows that is hard to read and manage static associated
values with each case. It is hard to add or remove case as it would
require to add or remove code in four different places in file. Also
static associated value like `UIBezierPath` is recreated each time the
property is computed while it's constant.

```swift
enum Suit {
case spades
case hearts
case diamonds
case clubs

var simpleDescription: String {
switch self {
case .spades:
return "spades"
case .hearts:
return "hearts"
case .diamonds:
return "diamonds"
case .clubs:
return "clubs"
}
}

var color: UIColor {
switch self {
case .spades:
return .blackColor()
case .hearts:
return .redColor()
case .diamonds:
return .redColor()
case .clubs:
return .blackColor()
}
}

var symbol: String {
switch self {
case .spades:
return "♠"
case .hearts:
return "♥"
case .diamonds:
return "♦"
case .clubs:
return "♣"
}
}

var bezierPath: UIBezierPath {
switch self {
case .spades:
let path = UIBezierPath()
// omitted lines ...
return path
case .hearts:
let path = UIBezierPath()
// omitted lines ...
return path
case .diamonds:
let path = UIBezierPath()
// omitted lines ...
return path
case .clubs:
let path = UIBezierPath()
// omitted lines ...
return path
}
}
}
```

## Proposed solution

Support stored properties for enum cases just as each case were an
instance. Case properties are initialized block after each case
declaration.

```swift
enum Suit {
let simpleDescription: String
let color: UIColor
let symbol: String
let bezierPath: UIBezierPath

case spades {
simpleDescription = "spades"
color = .blackColor()
symbol = "♠"
let bezierPath = UIBezierPath()
// omitted lines ...
self.bezierPath = bezierPath
}

case hearts {
simpleDescription = "hearts"
color = .redColor()
symbol = "♥"
let bezierPath = UIBezierPath()
// omitted lines ...
self.bezierPath = bezierPath
}

case diamonds {
simpleDescription = "diamonds"
color = .redColor()
symbol = "♦"
let bezierPath = UIBezierPath()
// omitted lines ...
self.bezierPath = bezierPath
}

case clubs {
simpleDescription = "clubs"
color = .blackColor()
symbol = "♣"
let bezierPath = UIBezierPath()
// omitted lines ...
self.bezierPath = bezierPath
}
}

let symbol = Suit.spades.symbol // "♠"
```

The proposed solution improves:
- Readability as cases are closer with their related data;
- Improves code maintainability as a case can be removed or added in one place;
- Improved performance as there is no need to recreate static values;
- ~30% less lines of code in given example.

## Detailed design

 Stored properties

Enum stored properties are supported the same way they are supported
for structs can classes. Unlike enum associated values, stored
properties are static to case and are shared for the same case.

Properties are accessed:
```swift
let simpleDescription = Suit.spades.simpleDescription
```

Mutable properties can be set:
```swift
Suit.spades.simpleDescription = "new simple description"
```

 Initialization

If enum has uninitialized stored property it must be initialized in a
block after each case declaration. The block work the same way as
struct initialization. At the end of initialization block all
properties must be initialized.

```swift
enum Suit {
var simpleDescription: String

case spades {
simpleDescription = "spades"
}
}
```

Initialization block can be combine with use of `rawValue`:

```swift
enum Suit: Int {
var simpleDescription: String

case spades = 1 {
simpleDescription = "spades"
}
}
```
or associated values of the case:

```swift
enum Suit {
var simpleDescription: String

case spades(Int) {
simpleDescription = "spades"
}
}
```

## Impact on existing code

Stored properties for enums are not currently not 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-29 Thread Leonardo Pessoa via swift-evolution
I think that's the case with enums. You're changing their current behaviour of 
only having stored values to one in which it's computed (even if only once and 
then stored). Enums are IMO something that have a static value you know 
beforehand and can count on. That's why I'm not fond of the accessor proposal. 
Otherwise I think we're transforming enums into a closed set of struct 
instances and one could do that already by using a private init.


> On 29 May 2016, at 3:38 am, Jānis Kiršteins via swift-evolution 
>  wrote:
> 
> I agree with the argument about use of "where", not replacing the raw
> value and having some kind of initialization block. But I cannot see
> why "accessors" concept is any better than stored properties to solve
> the particular problem. The "accessors" concept has much wider scope
> than enums and is a separate proposal.
> 
> On Sat, May 28, 2016 at 11:39 PM, Brent Royal-Gordon
>  wrote:
 - Abusing rawValue is just that: an abuse.
>>> 
>>> My original proposal does not replace rawValue and is compatible with it.
>> 
>> `rawValue` has a different purpose from how you're using it. It's supposed 
>> to allow you to convert your type to some other *equivalent* type, like an 
>> equivalent integer or string. Moreover, it's supposed to allow you to 
>> *reconstruct* the instance from the raw value—remember, `RawRepresentable` 
>> has an `init(rawValue:)` requirement.
>> 
>> It is *not* supposed to be an ancillary bag of information on the side. 
>> You're cramming a square peg into a round hole here.
>> 
>> (Also, if you use `rawValue` for an ancillary bag of information, that means 
>> you *can't* use it on the same type for its intended purpose. For instance, 
>> you would not be able to assign numbers to your Planet enum's cases to help 
>> you serialize them or bridge them to Objective-C. That's not good.)
>> 
 - Using `where` just doesn't match the use of `where` elsewhere in the 
 language; everywhere else, it's some kind of condition.
>>> 
>>> It is also used in generic type constraints. Plus it reads like human
>>> language: `case mercury where (mass: 3.303e+23, radius: 2.4397e6)`
>> 
>> But a generic constraint is also a type of condition: it specifies types 
>> which are permitted and divides them from types that are not.
>> 
>> This is *not* a condition. It's not anything like a condition. It's simply 
>> not consistent with anything else in the language.
>> 
 - Dictionaries are the most straightforward way to handle this with the 
 current language, but their lack of exhaustiveness checking is a problem.
>>> 
>>> Dictionaries can be used as workaround, but they cannot (lack of
>>> exhaustiveness) solve the problem.
>> 
>> I agree that they're a halfway solution.
>> 
>> If `ValuesEnumerable` were to be accepted (and to have a generic requirement 
>> for its `allValues` property), you could write a Dictionary-like type which 
>> ensured at initialization time that it was exhaustive. That's not as good as 
>> compile time, but it's not bad—sort of a three-quarters solution.
>> 
>>struct ExhaustiveDictionary> ValuesEnumerable>: Collection, DictionaryLiteralConvertible {
>>private var dictionary: [Key: Value]
>> 
>>init(dictionaryLiteral elements: (Key, Value)...) {
>>dictionary = [:]
>>for (k, v) in elements {
>>dictionary[k] = v
>>}
>> 
>>if dictionary.count != Key.allValues.count {
>>let missingKeys = Key.allValues.filter { 
>> dictionary[$0] == nil }
>>preconditionFailure("ExhaustiveDictionary is 
>> missing elements from \(Key.self): \(missingKeys)")
>>}
>>}
>> 
>>var startIndex: Dictionary.Index {
>>return dictionary.startIndex
>>}
>>var endIndex: Dictionary.Index {
>>return dictionary.endIndex
>>}
>>subscript(index: Dictionary.Index) -> (Key, Value) {
>>return dictionary[index]
>>}
>>func index(after i: Dictionary.Index) -> Dictionary.Index {
>>return dictionary.index(after: i)
>>}
>> 
>>subscript(key: Key) -> Value {
>>get { return dictionary[key]! }
>>set { dictionary[key] = newValue }
>>}
>>}
>> 
 What I would do is borrow the "accessors" concept from the property 
 behaviors proposal and extend it so that it supported both functions and 
 variables.
>>> 
>>> Wouldn't accessor just be a redundant keyword here? Currently enums do
>>> not support stored properties, so I guess there is no extra need to
>>> mark 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-29 Thread Jānis Kiršteins via swift-evolution
I agree with the argument about use of "where", not replacing the raw
value and having some kind of initialization block. But I cannot see
why "accessors" concept is any better than stored properties to solve
the particular problem. The "accessors" concept has much wider scope
than enums and is a separate proposal.

On Sat, May 28, 2016 at 11:39 PM, Brent Royal-Gordon
 wrote:
>>> - Abusing rawValue is just that: an abuse.
>>
>> My original proposal does not replace rawValue and is compatible with it.
>
> `rawValue` has a different purpose from how you're using it. It's supposed to 
> allow you to convert your type to some other *equivalent* type, like an 
> equivalent integer or string. Moreover, it's supposed to allow you to 
> *reconstruct* the instance from the raw value—remember, `RawRepresentable` 
> has an `init(rawValue:)` requirement.
>
> It is *not* supposed to be an ancillary bag of information on the side. 
> You're cramming a square peg into a round hole here.
>
> (Also, if you use `rawValue` for an ancillary bag of information, that means 
> you *can't* use it on the same type for its intended purpose. For instance, 
> you would not be able to assign numbers to your Planet enum's cases to help 
> you serialize them or bridge them to Objective-C. That's not good.)
>
>>> - Using `where` just doesn't match the use of `where` elsewhere in the 
>>> language; everywhere else, it's some kind of condition.
>>
>> It is also used in generic type constraints. Plus it reads like human
>> language: `case mercury where (mass: 3.303e+23, radius: 2.4397e6)`
>
> But a generic constraint is also a type of condition: it specifies types 
> which are permitted and divides them from types that are not.
>
> This is *not* a condition. It's not anything like a condition. It's simply 
> not consistent with anything else in the language.
>
>>> - Dictionaries are the most straightforward way to handle this with the 
>>> current language, but their lack of exhaustiveness checking is a problem.
>>
>> Dictionaries can be used as workaround, but they cannot (lack of
>> exhaustiveness) solve the problem.
>
> I agree that they're a halfway solution.
>
> If `ValuesEnumerable` were to be accepted (and to have a generic requirement 
> for its `allValues` property), you could write a Dictionary-like type which 
> ensured at initialization time that it was exhaustive. That's not as good as 
> compile time, but it's not bad—sort of a three-quarters solution.
>
> struct ExhaustiveDictionary ValuesEnumerable>: Collection, DictionaryLiteralConvertible {
> private var dictionary: [Key: Value]
>
> init(dictionaryLiteral elements: (Key, Value)...) {
> dictionary = [:]
> for (k, v) in elements {
> dictionary[k] = v
> }
>
> if dictionary.count != Key.allValues.count {
> let missingKeys = Key.allValues.filter { 
> dictionary[$0] == nil }
> preconditionFailure("ExhaustiveDictionary is 
> missing elements from \(Key.self): \(missingKeys)")
> }
> }
>
> var startIndex: Dictionary.Index {
> return dictionary.startIndex
> }
> var endIndex: Dictionary.Index {
> return dictionary.endIndex
> }
> subscript(index: Dictionary.Index) -> (Key, Value) {
> return dictionary[index]
> }
> func index(after i: Dictionary.Index) -> Dictionary.Index {
> return dictionary.index(after: i)
> }
>
> subscript(key: Key) -> Value {
> get { return dictionary[key]! }
> set { dictionary[key] = newValue }
> }
> }
>
>>> What I would do is borrow the "accessors" concept from the property 
>>> behaviors proposal and extend it so that it supported both functions and 
>>> variables.
>>
>> Wouldn't accessor just be a redundant keyword here? Currently enums do
>> not support stored properties, so I guess there is no extra need to
>> mark properties with any special keyword.
>
> The keyword is mainly to indicate the unusual syntax at the definition site, 
> where you only have to specify the name of the accessor you're defining, not 
> a `func` or `var` keyword, a return type, or even parameter names. (Like 
> `willSet`, there's a default parameter name you can use.) Secondarily, 
> though, I think it's helpful to indicate very explicitly that this is not an 
> ordinary method or property definition, even if the compiler could perhaps 
> sort things out without it. `accessor` is something a user can Google if 
> they've never seen it before.
>
>> Property accessors might work for 

Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-28 Thread Brent Royal-Gordon via swift-evolution
>> - Abusing rawValue is just that: an abuse.
> 
> My original proposal does not replace rawValue and is compatible with it.

`rawValue` has a different purpose from how you're using it. It's supposed to 
allow you to convert your type to some other *equivalent* type, like an 
equivalent integer or string. Moreover, it's supposed to allow you to 
*reconstruct* the instance from the raw value—remember, `RawRepresentable` has 
an `init(rawValue:)` requirement.

It is *not* supposed to be an ancillary bag of information on the side. You're 
cramming a square peg into a round hole here.

(Also, if you use `rawValue` for an ancillary bag of information, that means 
you *can't* use it on the same type for its intended purpose. For instance, you 
would not be able to assign numbers to your Planet enum's cases to help you 
serialize them or bridge them to Objective-C. That's not good.)

>> - Using `where` just doesn't match the use of `where` elsewhere in the 
>> language; everywhere else, it's some kind of condition.
> 
> It is also used in generic type constraints. Plus it reads like human
> language: `case mercury where (mass: 3.303e+23, radius: 2.4397e6)`

But a generic constraint is also a type of condition: it specifies types which 
are permitted and divides them from types that are not.

This is *not* a condition. It's not anything like a condition. It's simply not 
consistent with anything else in the language.

>> - Dictionaries are the most straightforward way to handle this with the 
>> current language, but their lack of exhaustiveness checking is a problem.
> 
> Dictionaries can be used as workaround, but they cannot (lack of
> exhaustiveness) solve the problem.

I agree that they're a halfway solution.

If `ValuesEnumerable` were to be accepted (and to have a generic requirement 
for its `allValues` property), you could write a Dictionary-like type which 
ensured at initialization time that it was exhaustive. That's not as good as 
compile time, but it's not bad—sort of a three-quarters solution.

struct ExhaustiveDictionary: Collection, DictionaryLiteralConvertible {
private var dictionary: [Key: Value]

init(dictionaryLiteral elements: (Key, Value)...) {
dictionary = [:]
for (k, v) in elements {
dictionary[k] = v
}

if dictionary.count != Key.allValues.count {
let missingKeys = Key.allValues.filter { 
dictionary[$0] == nil }
preconditionFailure("ExhaustiveDictionary is 
missing elements from \(Key.self): \(missingKeys)")
}
}

var startIndex: Dictionary.Index {
return dictionary.startIndex
}
var endIndex: Dictionary.Index {
return dictionary.endIndex
}
subscript(index: Dictionary.Index) -> (Key, Value) {
return dictionary[index]
}
func index(after i: Dictionary.Index) -> Dictionary.Index {
return dictionary.index(after: i)
}   

subscript(key: Key) -> Value {
get { return dictionary[key]! }
set { dictionary[key] = newValue }
}
}

>> What I would do is borrow the "accessors" concept from the property 
>> behaviors proposal and extend it so that it supported both functions and 
>> variables.
> 
> Wouldn't accessor just be a redundant keyword here? Currently enums do
> not support stored properties, so I guess there is no extra need to
> mark properties with any special keyword.

The keyword is mainly to indicate the unusual syntax at the definition site, 
where you only have to specify the name of the accessor you're defining, not a 
`func` or `var` keyword, a return type, or even parameter names. (Like 
`willSet`, there's a default parameter name you can use.) Secondarily, though, 
I think it's helpful to indicate very explicitly that this is not an ordinary 
method or property definition, even if the compiler could perhaps sort things 
out without it. `accessor` is something a user can Google if they've never seen 
it before.

> Property accessors might work for enums with associated values, but
> not so well without them.

The two have nothing to do with each other. I showed your planets example, 
which has no associated values but uses accessors just fine.

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-27 Thread Brent Royal-Gordon via swift-evolution
> The suggested solution based on 'accessor' - will create assotiated 
> properties each time the enum instace created, for each instance of enum type.

No; property accessors would be either computed or constant (so that all 
instances of a given case can share storage). This is much the way they would 
behave if they were included in behaviors.

You could write a property accessor with a setter, but it would have to be 
computed, and manipulate `self`'s cases and associated values:

enum Optional {
accessor var unwrapped: T { get set }

case none {
unwrapped {
get { fatalError("No value") }
set { self = .some(newValue) }
}
}
case some (_ value: T) {
unwrapped {
get { return value }
set { self = .some(newValue) }
}
}
}

-- 
Brent Royal-Gordon
Architechies

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-27 Thread Vladimir.S via swift-evolution
Correct me if I'm wrong, but this idea with accessors is not the same as 
static properties for each case. The one of ideas of initial proposal - 
static(!) values would be created only once and it is important in case it 
is expensive to create such value(or if should be created only once per case)


The suggested solution based on 'accessor' - will create assotiated 
properties each time the enum instace created, for each instance of enum type.


We can have something like the example with accessors now :

enum MyError: ErrorProtocol {
struct MyErrorInfo {
let localizedFailureReason: String
let url: String
}

case fileNotFound(url: String)
case fileIsCorrupt(url: String)

var info : MyErrorInfo {
switch self {
case fileNotFound(let url) : return 
MyErrorInfo(localizedFailureReason: "File \"\(url.lowercased())\" not 
found.", url: url)


case fileIsCorrupt(let url) : return 
MyErrorInfo(localizedFailureReason: "File \"\(url.lowercased())\"  is 
corrupt.", url: url)

}
}
}

var e = MyError.fileNotFound(url: "http://something.some;)
var info = e.info
print(info.localizedFailureReason, info.url)

But yes, such MyErrorInfo will be created on each `info.` call. This is 
worse that create MyErrorInfo once per each enum instance initialization, 
but IMO these solutions are close enough.


In any case, I don't see why tuple for enum and enum with `accessor` can 
not co-exists.


On 27.05.2016 2:28, Charles Srstka via swift-evolution wrote:

On May 26, 2016, at 4:47 PM, Brent Royal-Gordon via swift-evolution
> wrote:

- Abusing rawValue is just that: an abuse.


In addition, enums with associated types can’t have rawValues.

Why is this relevant, you may ask? Because error enums are a huge use case
for something like this. Being able to do the below would be great:

enum MyError: ErrorProtocol {
accessor var localizedFailureReason: String
accessor var url: NSURL

case FileNotFound(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ??
“”)\” not found.”
self.url = url
}

case FileIsCorrupt(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ??
“”)\” is corrupt.”
self.url = url
}
}

This would be much cleaner than the existing method of using a switch to
create a userInfo dictionary for creating an NSError to send to
-[NSApplication presentError:] and similar methods.

Charles



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


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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-26 Thread Charles Srstka via swift-evolution
> On May 26, 2016, at 4:47 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> - Abusing rawValue is just that: an abuse.

In addition, enums with associated types can’t have rawValues.

Why is this relevant, you may ask? Because error enums are a huge use case for 
something like this. Being able to do the below would be great:

enum MyError: ErrorProtocol {
accessor var localizedFailureReason: String
accessor var url: NSURL

case FileNotFound(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ?? “”)\” 
not found.”
self.url = url
}

case FileIsCorrupt(url: NSURL) {
self.localizedFailureReason = “File \"\(url.lastPathComponent ?? “”)\” 
is corrupt.”
self.url = url
}
}

This would be much cleaner than the existing method of using a switch to create 
a userInfo dictionary for creating an NSError to send to -[NSApplication 
presentError:] and similar methods.

Charles

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


Re: [swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-26 Thread Matthew Johnson via swift-evolution

> On May 26, 2016, at 4:47 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> The proposed solution is to have single static initializer for each
>> enum case that initializes stored properties. For example,
> 
> My opinions so far:
> 
> - Abusing rawValue is just that: an abuse.
> 
> - Using `where` just doesn't match the use of `where` elsewhere in the 
> language; everywhere else, it's some kind of condition.
> 
> - Dictionaries are the most straightforward way to handle this with the 
> current language, but their lack of exhaustiveness checking is a problem.
> 
> What I would do is borrow the "accessors" concept from the property behaviors 
> proposal and extend it so that it supported both functions and variables. 
> Then I would let you write this:
> 
>   enum Planet {
>  accessor var mass: Float
>  accessor var radius: Float
>  
>  case mercury {
> mass = 3.303e+23
> radius = 2.4397e6
>  }
>  case venus {
> mass = 4.869e+24
> radius = 6.0518e6
>  }
>  case earth {
> mass = 5.976e+24
> radius = 6.37814e6
>  }
>  case mars {
> mass = 6.421e+23
> radius = 3.3972e6
>  }
>  case jupiter {
> mass = 1.9e+27
> radius = 7.1492e7
>  }
>  case saturn {
> mass = 5.688e+26
> radius = 6.0268e7
>  }
>  case uranus {
> mass = 8.686e+25
> radius = 2.5559e7
>  }
>  case neptune {
> mass = 1.024e+26
> radius = 2.4746e7
>  }
>   }
> 
> You would also be able to declare methods like this; each implementation 
> would just look like `methodName { code }`. And you could provide default 
> implementations too:
> 
>   enum Planet {
>  accessor var mass: Float
>  accessor var radius: Float
>  accessor var habitable: Bool = false
>  
>  case mercury {
> mass = 3.303e+23
> radius = 2.4397e6
>  }
>  case venus {
> mass = 4.869e+24
> radius = 6.0518e6
>  }
>  case earth {
> mass = 5.976e+24
> radius = 6.37814e6
> habitable = true
>  }
>  case mars {
> mass = 6.421e+23
> radius = 3.3972e6
>  }
>  case jupiter {
> mass = 1.9e+27
> radius = 7.1492e7
>  }
>  case saturn {
> mass = 5.688e+26
> radius = 6.0268e7
>  }
>  case uranus {
> mass = 8.686e+25
> radius = 2.5559e7
>  }
>  case neptune {
> mass = 1.024e+26
> radius = 2.4746e7
>  }
>   }
> 

This is the first really interesting (to me) idea in the thread.  I think I 
like it but need to give it more thought to decide for sure. 

One really interesting thing we could do to build on this would be to introduce 
the associated value names inside the scope of each case as if they were member 
variables:

enum Foo {
accessor func bar() -> Int

case baz(val: Int) {
// val is in scope here
func bar() {
return val
}
}
}



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

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


[swift-evolution] [Proposal] Enums with static stored properties for each case

2016-05-25 Thread Jānis Kiršteins via swift-evolution
Hello everyone,

Currently Swift only supports computed properties for each enum case.
If you want to somehow get static values with each case you would
probably do it like this:

enum Planet {
case mercury
case venus
case earth
case mars
case jupiter
case saturn
case uranus
case neptune

var mass: Float {
switch self {
case .mercury: return 3.303e+23
case .venus: return 4.869e+24
case .earth: return 5.976e+24
case .mars: return 6.421e+23
case .jupiter: return 1.9e+27
case .saturn: return 5.688e+26
case .uranus: return 8.686e+25
case .neptune: return 1.024e+26
}
}

var radius: Float {
switch self {
case .mercury: return 2.4397e6
case .venus: return 6.0518e6
case .earth: return 6.37814e6
case .mars: return 3.3972e6
case .jupiter: return 7.1492e7
case .saturn: return 6.0268e7
case .uranus: return 2.5559e7
case .neptune: return 2.4746e7
}
}
}

However I see two problems with this approach:

1. These value definitions are spread out and difficult to read and
maintain (especially if you have many computed properties for each
enum case);
2. These values are not static. They are computed each time property
is accessed. This can be a problem when value is expensive to create.

The proposed solution is to have single static initializer for each
enum case that initializes stored properties. For example,

enum Planet {
var mass: Float
var radius: Float

static init(mass: Float, radius: Float) {
self.mass = mass
self.radius = radius
}

case mercury where (mass: 3.303e+23, radius: 2.4397e6)
case venus where (mass: 4.869e+24, radius: 6.0518e6)
case earth where (mass: 5.976e+24, radius: 6.37814e6)
case mars where (mass: 6.421e+23, radius: 3.3972e6)
case jupiter where (mass: 1.9e+27, radius: 7.1492e7)
case saturn where (mass: 5.688e+26, radius: 6.0268e7)
case uranus where (mass: 8.686e+25, radius: 2.5559e7)
case neptune where (mass: 1.024e+26, radius: 2.4746e7)
}

This approach do not affect enums that have raw or associated values,
or custom enum initializers:

case A = "A" where (id: 0)

or

case B(Int, Int, Int) where (id: 0)

Benefits:
1. Less verbosity
2. Improved readability
3. Related values are closer to each other
4. Static values are not recomputed
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution