On 26.05.2016 23:03, Leonardo Pessoa wrote:
I get it and think this was really very interesting in Delphi and I
wouldn't mind having something like this in Swift. But despite being able
to extend associated information through the use of another array we'd
still have more verbosity and scattering than with tuples to implement the
examples discussed.
At this moment I think your proposal for tuples as raw value for enum is
the best. So we can ask just to support tuples(not other types, at least
yet) as raw type and use tuple values directly on enum instance(without
`.rawValue.`). The question is if this is doable and if there is a support
for this in community and in core team. (even for post Swift 3.0 era)
As I understand, for this we need implicit implementation of Equatable for
tuple as raw value and probably of RawRepresentable.
>And we can already have enum dictionaries just not
checking automatically if all enum values have been covered. Moreover there
is no loss in having both solutions.
As for dictionary. I don't think of it as implementation detail for static
stored properties for each case. Such dictionary could be helpful in other
situations when you need assign some value for each enum case in your code.
*The main point* is a feature that compiler checks that value is assigned
for *each* case.
For example, in your code you need to assign color for each case in
Planets. You can do this in switch:
switch e {
case .earth : color = colorA
case .moon : color = colorB
}
but instead you can create a dict:
let planetToColor = [Planet.earth : colorA, .moon : colorB]
and use as planetToColor[e]! // yes, have to use `!` here
But, this is *not safe*(but very handy and useful) - as if you *add* new
case in enum (let's say .mars) you will not be notified(in opposite to
switch) that your planetToColor must me changed also - it does not contain
color for .mars. You will know about this only in runtime.
So, it will be very good for our code, if we have such dictionary which
will check at compile time that all cases are presented as keys in it.
I mentioned the values() method also because I miss a way to iterate
through all the values on an enum and since it seems we're discussing the
entire way to work with enums here it was worth bringing it up.
There was "ValueEnumerable protocol with derived implementation for enums"
thread in this mailing list, you can review discussion in it regarding
"values()" feature.
I also wish someone create a proposal to improve enums in a number of ways.
---------------------------------------------------------------------------
From: Vladimir.S <mailto:[email protected]>
Sent: 26/05/2016 03:06 PM
To: Leonardo Pessoa <mailto:[email protected]>
Cc: swift-evolution <mailto:[email protected]>
Subject: Re: [swift-evolution] [Proposal] Enums with static
storedpropertiesforeach case
Yes, this was mentioned in a similar thread in this email list earlier.
There is even some proposal for such .values() for Swift enums.
But this values() in Java is not the same thing as discussed dictionary
with *keys* of enum type or Delphi's arrays with *index* of enum type.
Could you write Java's example for array/dictionary of String which
*index*(or key) will be of enum type? *And* compiler will check that value
for each enum case is set in case of array of constants like:
MyConsts : array [TMyEnum] of String = ('just one', 'two here')
// compiler will always check that value assigned for each case
On 26.05.2016 20:58, Leonardo Pessoa wrote:
Java enums automatically have a static values() method that return an array
with all values in an enum.
---------------------------------------------------------------------------
From: Vladimir.S via swift-evolution <mailto:[email protected]>
Sent: 26/05/2016 02:36 PM
To: Ross O'Brien <mailto:[email protected]>
Cc: swift-evolution <mailto:[email protected]>
Subject: Re: [swift-evolution] [Proposal] Enums with static stored
propertiesforeach case
On 26.05.2016 19:50, Ross O'Brien wrote:
Perhaps there's an argument to be made for a sort of 'enumDictionary' type
- a dictionary whose keys are all the cases of an enum, and is thus
guaranteed to produce a value.
In Delphi(Pascal) you can define an array with indexes of enum type i.e.:
type
TMyEnum = (One, Two)
var
MyVal : array[TMyEnum] of String
const
MyConsts : array [TMyEnum] of String = ('just one', 'two here')
// compiler will check that values for each enum were specified here
,so you can do
var e: TMyEnum
e := One;
MyVal[e] := 'hello';
s2 := MyConsts[e];
This is really useful and used a lot. And this is safe in meaning compiler
will notify you if you changed the enum - you'll have to change such
constant array.
I wish we'll have something like this in Swift.
I think the question I have is how you'd access the values, syntactically.
To use the Planet example, if '.earth' is a value of the Planet enum, is
'.earth.mass' an acceptable way to access its mass? Or perhaps
'Planet[.earth].mass'?
Just like .rawValue currently, i.e.
let e = Planet.earth
print(e.mass, e.description)
On Thu, May 26, 2016 at 4:43 PM, Vladimir.S via swift-evolution
<[email protected] <mailto:[email protected]>> wrote:
Or(if we are sure we'll don't forget to udpate `infoDict` in case of
new added case in future):
enum Planet {
case earth
case moon
struct PlanetInfo {
var mass: Double
var description: String
}
private static let infoDict = [
Planet.earth :
PlanetInfo(mass: 1.0, description:"Earth is our home"),
.moon:
PlanetInfo(mass: 0.2, description:"Just a moon"),
]
var info : PlanetInfo { return Planet.infoDict[self]! }
}
But I agree with you, IMO we need static stored properties for each
case.
On 26.05.2016 18 <tel:26.05.2016%2018>:15, Jānis Kiršteins wrote:
The problem is that PlanetInfo values are recreated each time while
they are static. Imagine if PlanetInfo where some type that
expensive
to create performance wise.
You could solve it by:
enum Planet {
struct PlanetInfo {
var mass: Double
var description: String
}
case earth
case moon
private static earthInfo = PlanetInfo(mass: 1.0, description:
"Earth is our home")
private static moonInfo = PlanetInfo(mass: 0.2, description:
"Just a moon")
var info : PlanetInfo {
switch self {
case earth: return PlanetInfo.earthInfo
case moon: return PlanetInfo.moonInfo
}
}
}
But that again more verbose. The proposed solution is explicit that
those properties are static for each case.
On Thu, May 26, 2016 at 5:58 PM, Vladimir.S via swift-evolution
<[email protected] <mailto:[email protected]>>
wrote:
I support the proposal, but couldn't the initial target be
achieved today
with such (more verbose,yes) solution? :
enum Planet {
struct PlanetInfo {
var mass: Double
var description: String
}
case earth
case moon
var info : PlanetInfo {
switch self {
case earth: return PlanetInfo(mass: 1.0,
description: "Earth is
our home")
case moon: return PlanetInfo(mass: 0.2,
description: "Just a
moon")
}
}
}
let e = Planet.earth
print(e, e.info.description)
let m = Planet.moon
print(m, m.info.description)
On 26.05.2016 8:26, Charlie Monroe via swift-evolution wrote:
What this proposal is asking for is an easier way to
have derived values
from enum cases. Asking for more flexible RawValues
means mass and radius
are not derived, they are the source of truth. It goes
against the whole
point of RawRepresentable. You are not saying ‘Mercury
is identified by
the case .mercury’, you are saying ‘Mercury is
identified by a mass of
3.303e+23’. It’s backwards.
I see what Janis meant in the first email. It's not that
the planet would
be identified by the mass or radius. It could very much be
case Mercury = 1 where (mass: 3, radius: 2),
- Mercury's rawValue would be 1.
The issue here is that sometimes you want additional
information with the
enum. There are many cases where you extend the enum with a
variable:
enum Error {
case NoError
case FileNotFound
...
var isFatal: Bool {
/// swtich over all values of self goes here.
}
var isNetworkError: Bool {
/// swtich over all values of self goes here.
}
var isIOError: Bool {
/// swtich over all values of self goes here.
}
}
What the propsal suggests is to simplify this to the
following:
enum Error {
var isFatal: Bool
case NoError where (isFatal: false, isNetworkError: false,
isIOError:
false)
case FileNotFound where (isFatal: true, isNetworkError:
false, isIOError:
true)
...
}
So that you assign the additional information to the enum
value itself.
Charlie
On 26 May 2016, at 1:47 PM, David Sweeris via
swift-evolution
<[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>> wrote:
On May 25, 2016, at 10:27 PM, Jacob
Bandes-Storch <[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>> wrote:
On Wed, May 25, 2016 at 8:15 PM, David Sweeris
via swift-evolution
<[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>> wrote:
On May 25, 2016, at 7:37 AM, Leonardo
Pessoa via swift-evolution
<[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>>
wrote:
Hi,
Couldn't this be solved by using
tuples? If not because the syntax
is not allowed I think this would be
more coherent to do it using
current syntax.
enum Planet : (mass: Float, 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)
}
This would be my preferred solution… AFAIK,
the only reason we
can’t do it now is that Swift currently
requires RawValue be an
integer, floating-point value, or string. I
don’t know why the
language has this restriction, so I can’t
comment on how hard it
would be to change.
- Dave Sweeris
Except you'd have to write
Planet.mercury.rawValue.mass, rather than
Planet.mercury.mass.
This could be one or two proposals: allow enums
with tuple RawValues,
and allow `TupleName.caseName.propertyName` to
access a tuple element
without going through .rawValue.
Good point… Has there been a thread on allowing
raw-valued enums to be
treated as constants of type `RawValue` yet? Either
way, removing the
restriction on what types can be a RawValue is
still my preferred
solution.
- Dave Sweeris
_______________________________________________
swift-evolution mailing list
[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
<mailto:[email protected]>
<mailto:[email protected]
<mailto:[email protected]>>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected] <mailto:[email protected]>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected] <mailto:[email protected]>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected] <mailto:[email protected]>
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution