RFC 0051 removed case functions with an explicit step 3: "Someone drafts an RFC to reimplement case functions in a sane fashion." This is a request for that RFC.
Why now
RFC 0026 proposed two features: the iftype conditional expression and specialised generic functions with iftype guards on method signatures. Only iftype was implemented. The specialised generic functions — the part that lets callers see a different method signature depending on a type parameter — need case methods to work.
The motivating example is ponylang/ponyc#1784: collection clone methods should return iso when the element type is shareable. Today Array[A].clone() always returns ref^ because there's no way to give a method two return types based on a type constraint. With iftype inside the body you can produce an iso in the shareable branch, but the caller still sees ref^ — the declared signature doesn't change.
With case methods, you could write:
fun clone(): Array[this->A!] ref^ => // default
fun clone(): Array[A] iso^ iftype A <: Any #share => // specialisation
The caller at Array[String val] would see the specialised signature and get iso^ directly — no match, no cast.
What went wrong before
The old case functions were syntactic sugar over match statements. The compiler merged multiple method bodies into a single function with a match, and the implementation was fragile — mostly unusable outside simple examples and a recurring source of compiler bugs. RFC 0051 removed them for those reasons.
What the new version needs to avoid
The new case methods should not be sugar over match. The old implementation's problems came from trying to merge separate definitions into one function with runtime dispatch. The specialised generic functions from RFC 0026 dispatch at compile time based on type parameter constraints — fundamentally different from the old runtime-value dispatch, and the implementation should reflect that.
References
RFC 0051 removed case functions with an explicit step 3: "Someone drafts an RFC to reimplement case functions in a sane fashion." This is a request for that RFC.
Why now
RFC 0026 proposed two features: the
iftypeconditional expression and specialised generic functions withiftypeguards on method signatures. Onlyiftypewas implemented. The specialised generic functions — the part that lets callers see a different method signature depending on a type parameter — need case methods to work.The motivating example is ponylang/ponyc#1784: collection
clonemethods should returnisowhen the element type is shareable. TodayArray[A].clone()always returnsref^because there's no way to give a method two return types based on a type constraint. Withiftypeinside the body you can produce anisoin the shareable branch, but the caller still seesref^— the declared signature doesn't change.With case methods, you could write:
The caller at
Array[String val]would see the specialised signature and getiso^directly — no match, no cast.What went wrong before
The old case functions were syntactic sugar over match statements. The compiler merged multiple method bodies into a single function with a match, and the implementation was fragile — mostly unusable outside simple examples and a recurring source of compiler bugs. RFC 0051 removed them for those reasons.
What the new version needs to avoid
The new case methods should not be sugar over match. The old implementation's problems came from trying to merge separate definitions into one function with runtime dispatch. The specialised generic functions from RFC 0026 dispatch at compile time based on type parameter constraints — fundamentally different from the old runtime-value dispatch, and the implementation should reflect that.
References