The below is structured as a proposal, but at the moment I just want to gather opinions and also see if this a non-starter or not. It includes options for adopting this in version 2 or the theoretical version 3. Putting dev effort aside for the time being, is this a reasonable thing to address and does it align with the desired approach?
## Summary ## Enhance the switch directive to not force fall-through behavior. Using switch is currently clunky and the available alternatives have their own compromises. It should not exist in its current form in the next major release. ## History ## The FreeMarker switch directive mimics the Java switch statement. It supports fall-through and this is the control flow unless break is encountered. The manual recommends against this directive due to this error-prone behavior. Later, the switch built-in was added which does not have the concept of fall-through. ## Goals ## * Avoid unnecessary syntactic noise caused by having to use the break directive * Avoid accidental fall-through by making it explicit when needed ## Motivation ## * Avoid the potential for repetition due to elseif as a replacement * Offer increased syntactic clarity compared to the built-in * Avoid the pitfalls of the current switch directive ## Description ## The basis of this proposal is inspired by the switch statement in the Go language (see https://yourbasic.org/golang/switch-statement/). Rather than the default being to fall-through and you have to use the break keyword to avoid it, instead the default is to not fall-through and you have to use the fallthrough keyword to get that behavior. Having explicit fall-through stops it being a pitfall whilst allowing the feature to be used if required. Go has avoided repeating the mistake of previous languages and presents a solution that seems obvious in hindsight. Approaches for adopting this could be: * Replace the switch directive in the next major version with the explicit fall-through version * Introduce a new switch directive with a new name * Have a global setting for which switch directive is used / available to templates * Add an optional parameter to the switch directive for whether it should fall-through or not; its default would be a config setting. If we did this perhaps we should consider in future being able to parse the switch's value parameter as optional (defaulting to true), taking further inspiration from Go. If we want fall-through to be explicit, it makes sense to add a fallthrough directive to act as the inverse of the break directive. The user would then use the break directive (as required) when using the current mode/directive for fall-through and the fallthrough directive (as required) when using the new mode/directive. For what should happen when using break in the new mode/directive and fallthrough in the old mode/directive: it could either be an error, or break will still break and fallthrough will do nothing (or perhaps go to the next case). ## Alternatives ## * Remove the switch directive altogether * Completely disallow fall-through and the break directive (have neither implicit nor explicit fall-through) * Add a more powerful match directive that supports pattern matching and takes inspiration from e.g. Java's switch expressions or Rust's pattern syntax ## Future work ## Reinstating switch as a first-class directive would open the door to allowing enhancements to it again. One (low hanging?) example: for a case directive's value parameter to be an expression it sometimes requires wrapping the expression in brackets (e.g. it doesn't for an equality comparison, but does for a greater than comparison); the parser could be enhanced to remove this requirement. --- Best regards, Simon Hartley