Introduce an "ExpressibleByCase" protocol (to facilitate struct-based enums with payload)

The example you use is the basis of my comments in the thread I linked.

The trouble is: it's verbose and ugly... and, like, absurdly so! Your example, is (understandably and mercifully) shorthand. As you probably realize, it leaves out two things:

  1. That each case needs to init the struct with a unique id for its case. Without this id, there is no way to tell if two value types represent an equal case.

  2. That each example func needs to pass along its arguments. This is so because we need to store the payload.

Here's a reasonable approximation of what a full example might look like (leaving out two init methods, to avoid introducing errors by retyping the String id twice):

struct Param {
  static let age = Param( "age" )
  static let volunteer = Param( "volunteer" )
  static let fullname = Param( "fullname" )

  static func age(date: Date) -> Param { Param( .age,date }
  static func fullname(first: String, second: String) -> Param { Param(.fullname,second) }
}

Now there's even more machinery we need to add to make this a usable enumerable type (the inits, tests for equality, payload getter, code to make it confirm to CaseIterable), but already, this is pretty ugly and repetative.

Another concern I have is that we're relying on overloading a var with a func. If the data type were simple, maybe that would be okay, but I wouldn't want to debug it, if something goes wrong.

All this mess and confusion might be alright for a single DataType in one file somewhere, but I can't see anyone being happy with repeating this pattern over and over again. That's a shame, because it works great, at the call-site.