Require parameter names for ENUM Associated Types?


(Steve Prescott) #1

Has there been any discussion of REQUIRING names for associated types in an enum?

e.g.,
  Current = “case error (String, Int)” // No names
  Proposed = “case error (errorString: String, errorCode: Int)” // Has names

I know that Swift allows this today — optionally. To me, it seems that requiring the parameter names would be more consistent with func syntax. The current syntax (defaulting to no names) leads to declaration of vars that look C-like, to me:

let myResult = Result.error (“It failed”, -999)


(Adrian Zubarev) #2

I’d rather would have the ability of overloading enum cases:

enum MyEnum {
     
    case a
    case a(Int)
    case a(label: Int)
    case a(Double)
}
I don’t know how enums work internally, but I spotted a bug recently where the compiler does not allow to declare a function with the same name as an enum case.

SR–3256

I think this is a side effect of this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 14:48:30, Steve Prescott via swift-evolution (swift-evolution@swift.org) schrieb:

Has there been any discussion of REQUIRING names for associated types in an enum?

e.g.,
Current = “case error (String, Int)” // No names
Proposed = “case error (errorString: String, errorCode: Int)” // Has names

I know that Swift allows this today — optionally. To me, it seems that requiring the parameter names would be more consistent with func syntax. The current syntax (defaulting to no names) leads to declaration of vars that look C-like, to me:

let myResult = Result.error (“It failed”, -999)

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


(Karl) #3

eek… I really would not like that at all.

if case .a(let value) = myEnumValue {
    // what is type(of: value)?
}

- Karl

···

On 29 Nov 2016, at 14:55, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I’d rather would have the ability of overloading enum cases:

enum MyEnum {
     
    case a
    case a(Int)
    case a(label: Int)
    case a(Double)
}
I don’t know how enums work internally, but I spotted a bug recently where the compiler does not allow to declare a function with the same name as an enum case.

SR–3256 <https://bugs.swift.org/browse/SR-3256>
I think this is a side effect of this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md


(Adrian Zubarev) #4

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
     
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:48:34, Karl (razielim@gmail.com) schrieb:

On 29 Nov 2016, at 14:55, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I’d rather would have the ability of overloading enum cases:

enum MyEnum {
      
    case a
    case a(Int)
    case a(label: Int)
    case a(Double)
}
I don’t know how enums work internally, but I spotted a bug recently where the compiler does not allow to declare a function with the same name as an enum case.

SR–3256

I think this is a side effect of this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md

eek… I really would not like that at all.

if case .a(let value) = myEnumValue {
// what is type(of: value)?
}

- Karl


(Charles Srstka) #5

Or default values:

enum MyEnum {
  case a
  case b(Int, string: String = “SomeDefault”)
}

Charles

···

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
     
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.


(Adrian Zubarev) #6

However there is a problem with pattern matching:

if case .b = myEnumValue { … }
Today we can ignore all the associated values of an enum case in pattern matching.

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:52:18, Adrian Zubarev (adrian.zubarev@devandartist.com) schrieb:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
      
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:48:34, Karl (razielim@gmail.com) schrieb:

On 29 Nov 2016, at 14:55, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I’d rather would have the ability of overloading enum cases:

enum MyEnum {
       
    case a
    case a(Int)
    case a(label: Int)
    case a(Double)
}
I don’t know how enums work internally, but I spotted a bug recently where the compiler does not allow to declare a function with the same name as an enum case.

SR–3256

I think this is a side effect of this proposal https://github.com/apple/swift-evolution/blob/master/proposals/0036-enum-dot.md

eek… I really would not like that at all.

if case .a(let value) = myEnumValue {
// what is type(of: value)?
}

- Karl


(Adrian Zubarev) #7

Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com) schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
      
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles


(Charles Srstka) #8

I’m thinking more of default values as an alternative to overloaded enum cases. Giving the second parameter a default value equal to whatever the first case would have been assuming would obviate the need for overloaded cases here, and wouldn’t break the ability to leave out the values by typing “if case .javaScript”. All of the usefulness, none of the calories.

Charles

···

On Nov 29, 2016, at 9:59 AM, Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:

Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com <mailto:cocoadev@charlessoft.com>) schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
      
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles


(Tony Allevato) #9

Why not:

case javascript(String, scope: Document?)

Your desired scenario looks like it's conceptually expressing that Document
is optional, so why not use the type to codify that?

···

On Tue, Nov 29, 2016 at 7:59 AM Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com)
schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {

    case a
    case b(Int)
    case b(Int, string: String)
}

Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles

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


(Derrick Ho) #10

I like the idea of overloading an enum type. The issue happens when we use
it in a switch statements. Currently the parameters can be excluded.
However, We can make it a rule that any overloaded enum requires the full
signature.

···

On Tue, Nov 29, 2016 at 10:59 AM Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com)
schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {

    case a
    case b(Int)
    case b(Int, string: String)
}

Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles

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


(Adrian Zubarev) #11

As I said before, the associated values can be excluded for pattern matching. I believe this way you can check against the enum case without producing any copy of the associated types right?!

var _kind: Byte {
         
    switch self {
             
    …
    case .javaScript: return 0x0D
    case .scopedJavaScript: return 0x0F
    …
    }
}
Assume we could overload the values by including additional labels to the enum case.

case javaScript(String)
case javaScript(String, scope: Document) // or more swifty `javascript(String, withScope: Document)`
Now I could check the case like this to solve the ambiguity.

switch self {
             

case .javaScript: return 0x0D
case .javaScript(_:withScope:): return 0x0F

}
Plus I don’t want to wrap values in optionals when there is no need for that.

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:03:12, Tony Allevato (allevato@google.com) schrieb:

Why not:

case javascript(String, scope: Document?)

Your desired scenario looks like it's conceptually expressing that Document is optional, so why not use the type to codify that?

On Tue, Nov 29, 2016 at 7:59 AM Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com) schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
       
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles

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


(Tony Allevato) #12

I suppose I'm not seeing why it's important to exclude the associated
values from pattern matching. What do you gain except saving a few
characters? What you're suggesting doesn't strike me as a significant
improvement over this:

case javascript(String, scope: Document?)
...

switch self {
  case .javascript(_, scope: .none): return 0x0D
  case .javascript: return 0x0F   // or case .javascript(_, scope: .some),
if you want to be explicit about the distinction between the two cases
}
···

On Tue, Nov 29, 2016 at 8:12 AM Adrian Zubarev < adrian.zubarev@devandartist.com> wrote:

As I said before, the associated values can be excluded for pattern
matching. I believe this way you can check against the enum case without
producing any copy of the associated types right?!

var _kind: Byte {

    switch self {

    …
    case .javaScript: return 0x0D
    case .scopedJavaScript: return 0x0F
    …
    }
}

Assume we could overload the values by including additional labels to the
enum case.

case javaScript(String)
case javaScript(String, scope: Document) // or more swifty `javascript(String, withScope: Document)`

Now I could check the case like this to solve the ambiguity.

switch self {


case .javaScript: return 0x0D
case .javaScript(_:withScope:): return 0x0F

}

Plus I don’t want to wrap values in optionals when there is no need for
that.

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:03:12, Tony Allevato (allevato@google.com)
schrieb:

Why not:

case javascript(String, scope: Document?)

Your desired scenario looks like it's conceptually expressing that
Document is optional, so why not use the type to codify that?

On Tue, Nov 29, 2016 at 7:59 AM Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com)
schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution < > swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {

    case a
    case b(Int)
    case b(Int, string: String)
}

Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles

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


(Adrian Zubarev) #13

I already said it, I don’t want to wrap my types into optionals when there is no need for that.

Plus what’s the need of default values in associated enum cases anyways? Just assume for a second that we could overload enum cases:

enum MyEnum {
   case a(Int)
   case a(Int, b: Int = 42)
}

let myEnumValue = MyEnum.a(0) // What will this produce? Or should we write `MyEnum.a(0, b:)` which is ugly from my point of view
However I see where this might work, but again, what’s the use case here?

enum MyEnum {
   case a(Int)
   case a(Int = 42, b: Int)
}

let a1 = MyEnum.a(0)
let a2 = MyEnum.a(b: 0)

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:19:16, Tony Allevato (allevato@google.com) schrieb:

I suppose I'm not seeing why it's important to exclude the associated values from pattern matching. What do you gain except saving a few characters? What you're suggesting doesn't strike me as a significant improvement over this:

case javascript(String, scope: Document?)
...

switch self {
  case .javascript(_, scope: .none): return 0x0D
  case . return 0x0F   // or case .javascript(_, scope: .some), if you want to be explicit about the distinction between the two cases
}

On Tue, Nov 29, 2016 at 8:12 AM Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
As I said before, the associated values can be excluded for pattern matching. I believe this way you can check against the enum case without producing any copy of the associated types right?!

var _kind: Byte {
          
    switch self {
              
    …
    case .javaScript: return 0x0D
    case .scopedJavaScript: return 0x0F
    …
    }
}
Assume we could overload the values by including additional labels to the enum case.

case javaScript(String)
case javaScript(String, scope: Document) // or more swifty `javascript(String, withScope: Document)`
Now I could check the case like this to solve the ambiguity.

switch self {
              

case .javaScript: return 0x0D
case .javaScript(_:withScope:): return 0x0F

}
Plus I don’t want to wrap values in optionals when there is no need for that.

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:03:12, Tony Allevato (allevato@google.com) schrieb:

Why not:

case javascript(String, scope: Document?)

Your desired scenario looks like it's conceptually expressing that Document is optional, so why not use the type to codify that?

On Tue, Nov 29, 2016 at 7:59 AM Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:
Hmm, I feel like default values wouldn’t work with overloaded enum cases.

In my own project I have something like this:

case javaScript(String)
case scopedJavaScript(String, scope: Document)

// But I'd like it to be:
case javaScript(String)
case javaScript(String, scope: Document)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 16:55:52, Charles Srstka (cocoadev@charlessoft.com) schrieb:

On Nov 29, 2016, at 9:52 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

I just showed a direction of what could be possible.

Personally I think it would be enough if we had this:

enum MyEnum {
        
    case a
    case b(Int)
    case b(Int, string: String)
}
Where .b can be overloaded by it’s associated types.

Or default values:

enum MyEnum {
case a
case b(Int, string: String = “SomeDefault”)
}

Charles

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


(Adrian Zubarev) #14

If we’re talking about non optional values here, then I don’t produce a possible expensive copy of my associated values (sure it depends on the type, COW etc.), but that’s my main point for excluding the the associated values.

Somewhere in my code I also have a semi schema subscript which evaluates the enum case like this:

if case .double = $0 { return true } else { return false }
There is just no better way for this check. I wish I could write something like return .double ~= $0 there.

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:19:16, Tony Allevato (allevato@google.com) schrieb:

I suppose I'm not seeing why it's important to exclude the associated values from pattern matching. What do you gain except saving a few characters?


(Tony Allevato) #15

If we’re talking about non optional values here, then I don’t produce a
possible expensive copy of my associated values (sure it depends on the
type, COW etc.), but that’s my main point for excluding the the associated
values.

Does matching against _ cause a copy to be made? I wouldn't expect it to
since it can never be used. If it does, I'd argue that's a bug.

Somewhere in my code I also have a semi schema subscript which evaluates
the enum case like this:

if case .double = $0 { return true } else { return false }

There is just no better way for this check. I wish I could write something
like return .double ~= $0 there.

We agree on this—I've had situations where I all I wanted to know was
whether an enum value matched a particular case, and a Boolean case
expression would be fantastic.

Re: your earlier message, I'm trying to understand why you want to avoid
wrapping your types in optionals when, if you can express both the presence
and absence of them in an overloaded case, that effectively means they
*are* optional? Is there a particular problem with Optional<T> that you're
trying to avoid? If you're already pattern matching to detect the enum
case, unwrapping the optional at the same time is no more difficult than if
it were non-optional.

I'm not convinced that overloading enum cases is something that should be
supported, but I'm about 90% on supporting default values. So I'm trying to
understand why you want this specific feature for your specific problem,
and how it could apply elsewhere.

···

On Tue, Nov 29, 2016 at 8:35 AM Adrian Zubarev < adrian.zubarev@devandartist.com> wrote:

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:19:16, Tony Allevato (allevato@google.com)
schrieb:

I suppose I'm not seeing why it's important to exclude the associated
values from pattern matching. What do you gain except saving a few
characters?


(Adrian Zubarev) #16

Don’t get me wrong, in my case default values with an optional will work just fine, but I don’t see how default values are better on associated types than:

// default values
enum Something {
     
      case a(String, Int? = nil, Int? = nil)
}

// vs.
enum Something {
      case a(String)
      case a(String, Int)
      case a(String, Int, Int)
}
When the enum is public, do you want the user to check for all the optionals. This could be really pesky, if you ask me.

if case a(let stringValue, .some(let firstInt), .some(let secondInt)) = … {}

// vs.

if case a(let stringValue, let firstInt, let secondInt) = … {}
How about this short example? How would you design an enum with default values? The idea here is to use the same enum case for number literals. Maybe the design of the API does not want something like case int(Int) and case double(Double) for any reasons.

enum Value {
     
    case string(String)
    case number(Int)
    case number(Double)
}

let intCase: Value = .number(1)
let doubleCase: Value = .number(2.0)

···

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:45:07, Tony Allevato (allevato@google.com) schrieb:

On Tue, Nov 29, 2016 at 8:35 AM Adrian Zubarev <adrian.zubarev@devandartist.com> wrote:
If we’re talking about non optional values here, then I don’t produce a possible expensive copy of my associated values (sure it depends on the type, COW etc.), but that’s my main point for excluding the the associated values.

Does matching against _ cause a copy to be made? I wouldn't expect it to since it can never be used. If it does, I'd argue that's a bug.

Somewhere in my code I also have a semi schema subscript which evaluates the enum case like this:

if case .double = $0 { return true } else { return false }
There is just no better way for this check. I wish I could write something like return .double ~= $0 there.

We agree on this—I've had situations where I all I wanted to know was whether an enum value matched a particular case, and a Boolean case expression would be fantastic.

Re: your earlier message, I'm trying to understand why you want to avoid wrapping your types in optionals when, if you can express both the presence and absence of them in an overloaded case, that effectively means they *are* optional? Is there a particular problem with Optional<T> that you're trying to avoid? If you're already pattern matching to detect the enum case, unwrapping the optional at the same time is no more difficult than if it were non-optional.

I'm not convinced that overloading enum cases is something that should be supported, but I'm about 90% on supporting default values. So I'm trying to understand why you want this specific feature for your specific problem, and how it could apply elsewhere.

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:19:16, Tony Allevato (allevato@google.com) schrieb:

I suppose I'm not seeing why it's important to exclude the associated values from pattern matching. What do you gain except saving a few characters?


(Tony Allevato) #17

Default values and overloaded cases don't (and in fact, shouldn't) be
conflated.

I support default values for associated values but I'm not yet ready to say
I'm in favor of overloaded cases. There's no ambiguity because your
Value.number example can't exist without overloads, and default values
don't create parameter lists that could mismatch like that (there's still
only one case, and it has all of the associated values regardless of how
many you specify at the time you create it).

Small self-contained examples like Value are nice, but entirely
hypothetical and a bit contrived. "Maybe the design of the API does not
want something" is difficult to convince me—I'd prefer to see a significant
real world situation where it's vital to have two cases with the same name
with differently typed payloads, which can't be expressed in a different
way. For example, in your Javascript example, I think the optionality of
that Document would be far better expressed as an Optional<Document> with a
default value of nil than creating an overload, and that solution
introduces far less complexity to the language than would introducing
arbitrary overloads.

···

On Tue, Nov 29, 2016 at 9:25 AM Adrian Zubarev via swift-evolution < swift-evolution@swift.org> wrote:

Don’t get me wrong, in my case default values with an optional will work
just fine, but I don’t see how default values are better on associated
types than:

// default values
enum Something {

      case a(String, Int? = nil, Int? = nil)
}

// vs.
enum Something {
      case a(String)
      case a(String, Int)
      case a(String, Int, Int)
}

When the enum is public, do you want the user to check for all the
optionals. This could be really pesky, if you ask me.

if case a(let stringValue, .some(let firstInt), .some(let secondInt)) = … {}

// vs.

if case a(let stringValue, let firstInt, let secondInt) = … {}

How about this short example? How would you design an enum with default
values? The idea here is to use the same enum case for number literals.
Maybe the design of the API does not want something like case int(Int)
and case double(Double) for any reasons.

enum Value {

    case string(String)
    case number(Int)
    case number(Double)
}

let intCase: Value = .number(1)
let doubleCase: Value = .number(2.0)

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:45:07, Tony Allevato (allevato@google.com)
schrieb:

On Tue, Nov 29, 2016 at 8:35 AM Adrian Zubarev < > adrian.zubarev@devandartist.com> wrote:

If we’re talking about non optional values here, then I don’t produce a
possible expensive copy of my associated values (sure it depends on the
type, COW etc.), but that’s my main point for excluding the the associated
values.

Does matching against _ cause a copy to be made? I wouldn't expect it to
since it can never be used. If it does, I'd argue that's a bug.

Somewhere in my code I also have a semi schema subscript which evaluates
the enum case like this:

if case .double = $0 { return true } else { return false }

There is just no better way for this check. I wish I could write something
like return .double ~= $0 there.

We agree on this—I've had situations where I all I wanted to know was
whether an enum value matched a particular case, and a Boolean case
expression would be fantastic.

Re: your earlier message, I'm trying to understand why you want to avoid
wrapping your types in optionals when, if you can express both the presence
and absence of them in an overloaded case, that effectively means they
*are* optional? Is there a particular problem with Optional<T> that you're
trying to avoid? If you're already pattern matching to detect the enum
case, unwrapping the optional at the same time is no more difficult than if
it were non-optional.

I'm not convinced that overloading enum cases is something that should be
supported, but I'm about 90% on supporting default values. So I'm trying to
understand why you want this specific feature for your specific problem,
and how it could apply elsewhere.

--
Adrian Zubarev
Sent with Airmail

Am 29. November 2016 um 17:19:16, Tony Allevato (allevato@google.com)
schrieb:

I suppose I'm not seeing why it's important to exclude the associated
values from pattern matching. What do you gain except saving a few
characters?

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


(Karl) #18

Yeah, we shouldn’t confuse these issues. Default values for enum payloads are something I also really want (in Swift 4 phase 2). Here’s my use-case:

public enum ReadError : Error {
    case otherError(description: String, location: StaticString? = #function) // <- currently an error, tuples can't have default values
}

And yes, you can use #function as a default value:

func doIt(_ str: String = #function) {
print("Called from \(str)")
}
func myFunc() { doIt() }

doIt() // Prints “Called from __lldb_expr_1” in REPL
myFunc() // Prints “Called from myFunc()”

I think that’s a more valuable use-case than overloaded values; so if they’re incompatible and we have to choose one, I’d go for default values.

- Karl

···

On 29 Nov 2016, at 18:41, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

Default values and overloaded cases don't (and in fact, shouldn't) be conflated.

I support default values for associated values but I'm not yet ready to say I'm in favor of overloaded cases. There's no ambiguity because your Value.number example can't exist without overloads, and default values don't create parameter lists that could mismatch like that (there's still only one case, and it has all of the associated values regardless of how many you specify at the time you create it).

Small self-contained examples like Value are nice, but entirely hypothetical and a bit contrived. "Maybe the design of the API does not want something" is difficult to convince me—I'd prefer to see a significant real world situation where it's vital to have two cases with the same name with differently typed payloads, which can't be expressed in a different way. For example, in your Javascript example, I think the optionality of that Document would be far better expressed as an Optional<Document> with a default value of nil than creating an overload, and that solution introduces far less complexity to the language than would introducing arbitrary overloads.


(Adrian Zubarev) #19

Fair point, the more and more I’m thinking about default values, the more I’m convinced here.

And yes, as I mentioned before, default value would solve the problem in my API. I’m thinking of adapting the pitched idea so I almost get the right behaviour for free when Swift 4 drops.

···

--
Adrian Zubarev
Sent with Airmail

Am 30. November 2016 um 04:32:17, Karl (razielim@gmail.com) schrieb:

On 29 Nov 2016, at 18:41, Tony Allevato via swift-evolution <swift-evolution@swift.org> wrote:

Default values and overloaded cases don't (and in fact, shouldn't) be conflated.

I support default values for associated values but I'm not yet ready to say I'm in favor of overloaded cases. There's no ambiguity because your Value.number example can't exist without overloads, and default values don't create parameter lists that could mismatch like that (there's still only one case, and it has all of the associated values regardless of how many you specify at the time you create it).

Small self-contained examples like Value are nice, but entirely hypothetical and a bit contrived. "Maybe the design of the API does not want something" is difficult to convince me—I'd prefer to see a significant real world situation where it's vital to have two cases with the same name with differently typed payloads, which can't be expressed in a different way. For example, in your Javascript example, I think the optionality of that Document would be far better expressed as an Optional<Document> with a default value of nil than creating an overload, and that solution introduces far less complexity to the language than would introducing arbitrary overloads.

Yeah, we shouldn’t confuse these issues. Default values for enum payloads are something I also really want (in Swift 4 phase 2). Here’s my use-case:

public enum ReadError : Error {
    case otherError(description: String, location: StaticString? = #function) // <- currently an error, tuples can't have default values
}

And yes, you can use #function as a default value:

func doIt(_ str: String = #function) {
print("Called from \(str)")
}
func myFunc() { doIt() }

doIt() // Prints “Called from __lldb_expr_1” in REPL
myFunc() // Prints “Called from myFunc()”

I think that’s a more valuable use-case than overloaded values; so if they’re incompatible and we have to choose one, I’d go for default values.

- Karl


(Steve Prescott) #20

As the original poster of this thread, I wanted to re-state the original question:

Should enums REQUIRE parameter names?

Pro: The syntax would more closely match that for functions, which requires names for all parameters (unless you say “_”) vs. the current syntax that is sort of C-like.
Con: More verbose

With this suggestion, your declaration of a variable that uses an enum would resemble calling a function. e.g.:

var myTeam = Team.football (name: “Redskins”, city: “Washington, DC”, quarterback: “Kirk Cousins”)

···

On Nov 30, 2016, at 5:14 AM, Adrian Zubarev via swift-evolution <swift-evolution@swift.org> wrote:

Fair point, the more and more I’m thinking about default values, the more I’m convinced here.

And yes, as I mentioned before, default value would solve the problem in my API. I’m thinking of adapting the pitched idea so I almost get the right behaviour for free when Swift 4 drops.

--
Adrian Zubarev
Sent with Airmail

Am 30. November 2016 um 04:32:17, Karl (razielim@gmail.com <mailto:razielim@gmail.com>) schrieb:

On 29 Nov 2016, at 18:41, Tony Allevato via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Default values and overloaded cases don't (and in fact, shouldn't) be conflated.

I support default values for associated values but I'm not yet ready to say I'm in favor of overloaded cases. There's no ambiguity because your Value.number example can't exist without overloads, and default values don't create parameter lists that could mismatch like that (there's still only one case, and it has all of the associated values regardless of how many you specify at the time you create it).

Small self-contained examples like Value are nice, but entirely hypothetical and a bit contrived. "Maybe the design of the API does not want something" is difficult to convince me—I'd prefer to see a significant real world situation where it's vital to have two cases with the same name with differently typed payloads, which can't be expressed in a different way. For example, in your Javascript example, I think the optionality of that Document would be far better expressed as an Optional<Document> with a default value of nil than creating an overload, and that solution introduces far less complexity to the language than would introducing arbitrary overloads.

Yeah, we shouldn’t confuse these issues. Default values for enum payloads are something I also really want (in Swift 4 phase 2). Here’s my use-case:

public enum ReadError : Error {
    case otherError(description: String, location: StaticString? = #function) // <- currently an error, tuples can't have default values
}

And yes, you can use #function as a default value:

func doIt(_ str: String = #function) {
print("Called from \(str)")
}
func myFunc() { doIt() }

doIt() // Prints “Called from __lldb_expr_1” in REPL
myFunc() // Prints “Called from myFunc()”

I think that’s a more valuable use-case than overloaded values; so if they’re incompatible and we have to choose one, I’d go for default values.

- Karl

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