ERROR: Tuple pattern element label 'data' must be 'string'

enum FeedAPI {
   case get(data: Data)
   case post(data: Data)
   case post(string: String)

   public var path : String {
       switch self {
 ///  ERROR: Tuple pattern element label 'data' must be 'string'
       case .get(data: _):
           return "/api/get/data"
       case .post(data: _):
           return "/api/post/data"
       case .post(string: _):
           return "/api/post/string"
       }
    }
}



let a = HTTP.post(data: Data())

Hi all,

So I have a mobile application. Heres a sample API that is used with a networking library. I have a public accessor variable which is called path. What it does take the current case FeedAPI Endpoint and give a path. However, when you do the switch on self , it doesn't let you use cases that have the same case signature name regardless if the parameter signatures are different. I need this because without it, the enum cases look quirky which in my opinion, not part of the swift coding style guide.

enum FeedAPI {
   case getData(body: Data)
   case postData(body: Data)
   case postString(body: String)

   public var path : String {
       switch self {
       case .get(body: _):
           return "/api/get/data"
       case .postData(body: _):
           return "/api/post/data"
       case . postString(body: _):
           return "/api/post/string"
       }
    }
}



let a = HTTP.postData(body: Data())

This likely fit better for Using Swift category.

Also found this SR-10077

1 Like

I think you are conflating such an enum the idea of a function with the naming split between the actual name and the parameters.

If you ignore the associated value, you would not be allowed to have :

enum FeedAPI
{
  case get
  case post
  case post
}

… so it makes sense to consider the enum case names as unique in their own right. In which case, as you have discovered :

enum FeedAPI
{
  case getData(Data)
  case postData(Data)
  case postString(String)
  
  public var path : String
  {
    switch self
    {
      case .getData(_):
        return "/api/get/data"
      case .postData(_):
        return "/api/post/data"
      case .postString(_):
        return "/api/post/string"
    }
  }
}

… works fine.

according to SE-0155 you should be able to have non-unique base enum name, as long as the full name is different

1 Like

Unfortunately, that document ends with :

A drafted version of this proposal considered allowing "overloaded" declaration of enum cases (same full-name, but with associated values with different types). We ultimately decided that this feature is out of the scope of this proposal.

1 Like

:frowning:

Couldn’t you just define a Payload enum or some such type to be the associated value for the main enum that could be either String or Data?

It's correct that SE-0155 doesn't allow same full name with different associated types.

In this case, though, the full names are get(data:), post(data:) and post(string:), so it is permissible. One key point of SE-0155 is to align enum cases with functions such that argument labels are considered part of the full name. If it's not working, then it's not yet implemented under the version of Swift that's being used.

3 Likes

The status seems to still be Accepted, not Implemented.

1 Like

This already works when you are declaring the enum. The problem seems to arise when you try to extract the associated value in something like a switch statement.

I definitely think that argument labels for enums should be part of the name. Thats in align with swift design philosophy. The way I did the workaround with case getData(Data) looks very clunky and verbose (reminds me of java). look at how clean case get(data: Data) or case get(Data) looks and imagine it being used in action , how much better the code would look. For me as a linguist, when I write code, I care a lot about semantics because if you can create baseline semantics for your code base, its easy to work with and coordinate with teams as the code base gets larger. Especially now, I think we as coders need to go back to linguistics concepts to build good AI because programming languages are languages after all!

I see enum cases semantically (specific to this instance) being used for "verbs" while the argument labels being nouns. In general, my point is, very powerful linguistic abstractions can be created from the Enum but the idea that argument labels cant be differentiated across cases, is a very limiting factor for creating powerful abstractions in Swift.

Enum within Enum. Yes its been considered but simple abstractions are the best abstractions. I will however go with this solution only for the reason being that it looks cleaner.

That is the simple abstraction? You enumerate the kinds of HTTP methods, and the ones that have a payload then can enumerate their payload kinds.

yes and payload is going to vary on each type of case so I dont want to make payload for each case of payloads. the point is regardless that enum cases should be allowed to have the same case name but allow change in signature.

I’m not sure I understand how writing multiple cases at the top level is better than writing multiple cases at the second level. You end up with the same combinations in the end, but a cleaner abstraction and a clear delineation of what is allowed in your API if the payloads types are enumerated by what’s allowed in each HTTP method. Isn’t that kind of the point of strongly typed languages, so you can define what’s allowed so the compiler can help you follow your rules?

It gets bloated quickly if we keep having to name one-off types every time we want something.

Plus, there’s nothing wrong with wanting to use full name to differentiate between cases.

Sounds like a variant of a bluff--a function that takes an enum but there is no enum cases, so you can't call the function. You can declare it but you can't use the cases? Hmm...