> But #if does, right? Why not #on? Yes, but in this analogy #if is more like #switch, or as #attempt. And #on is in a role similar to #elseif/#else, or #recover.
> <#on …> > Does ellipsis count as “least surprise”? I guess most could guess the meaning when they see it in an already existing template. But then, immagine randomly stopping developers on the street, and showing them #switch/#on sample code that doesn't yet have the branch that handles the rest of the values. And then asking them to guess how that's done. I think most would use #default. So that's better then, in my book. On Sat, Feb 10, 2024 at 3:05 PM Denis Bredelet <[email protected]> wrote: > Hi Daniel, > > > #else and #ifelse have no closing tag either. > > But #if does, right? Why not #on? > > > Nor does #recover. That's the > > style that was chosen back then. Brevity over correctness(?). > > > > <#on .other> would be rather strange. "Why don't they just have a keyword > > for the statement itself???". Also, developers won't invest much mental > > energy into learning a template language, so, the less surprising, the > > better. > > True… one last attempt then I’ll hide again: > <#on …> > Does ellipsis count as “least surprise”? > > Cheers, > — Denis. > > > > >> On Sat, Feb 10, 2024 at 9:45 AM Denis Bredelet <[email protected] > > > >> wrote: > >> > >> Hi > >>> Understood. > >>> > >>> One argument for supporting #break in #on: whitespace avoidance > >>> > >>> Because there's not an explicit closing tag for #case or #on, the use > of > >> #break in the following avoids a trailing newline: > >>> <#switch x> > >>> <#case 1>1<#break> > >>> <#default>not 1<#break> > >>> </#switch> > >> > >> 1. #on should have a close tag, for that reason. > >> 2. #break should work as normal inside #on. That is to allow exiting an > >> #on directive early, for example on a condition. > >> 3. #case should not be allowed together with #on > >> > >> I don’t know if #default should be replaced as well when using #on (it > >> doesn’t have a close tag!) > >> I suggest <#on .other> > >> > >> Cheers, > >> — Denis. > >> > >>> > >>> Do we just say that if they need that then they should use #case > >> instead? It could mean that we'd never we able to fully deprecate #case. > >>> > >>> --- > >>> Many thanks, > >>> Simon Hartley > >>> > >>> > >>> On Friday, 9 February 2024 at 23:29:28 GMT, Daniel Dekany < > >> [email protected]> wrote: > >>> > >>> > >>> > >>> > >>> > >>> Because both #switch and #list supports #break, of course it will break > >> out > >>> from the innermost one (whether it's a #switch, or a #break). > >>> > >>> #continue should only work with #list, however, it seems there's a bug > >>> here, and indeed, inside #switch it does the same as #break (that it's > >>> certainly present for 20 years or so). > >>> > >>> As of #on, we just don't care about #break, it's unsupported. So it > >> should > >>> only affect #list. Similarly as #continue should work... We can't > really > >>> fix that anymore for #case (or only with incomplatible_improvements... > >>> yeah, annoying), but for #on, we can fix that. > >>> > >>> I say, we don't want to support mixing #case and #on in the same > #switch. > >>> To keep things as simple as possible... (Well, if we want to do > >>> anything with #switch at all.) > >>> > >>>> On Fri, Feb 9, 2024 at 11:36 PM Simon Hartley > >>>> <[email protected]> wrote: > >>>> > >>>> I've looked into adding #on support to #switch and I think the > following > >>>> needs further consideration: how #break works in #switch with #on? > >>>> > >>>> When using #switch with #case in a #list, #break finds the #switch and > >>>> breaks out of that, rather than the #list. > >>>> <#list [1,2,3] as item> > >>>> <#switch item> > >>>> <#case 2> It's 2 <#break> <!-- Breaks from #switch, not #list > >> --> > >>>> <#default> Not 2 > >>>> </#switch> > >>>> </#list> > >>>> > >>>> Mixing #list with #on, what's the behavior? > >>>> 1. #break is in a #switch and so it breaks from that > >>>> 2. #break is in an #on and so throws an error because #on does not > allow > >>>> that > >>>> 3. #break acts like it's used by #list and so breaks from that, rather > >>>> than the #switch > >>>> <#list [1,2,3] as item> > >>>> <#switch item> > >>>> <#on 2> It's 2 <#break> <#-- break from #switch, break from > >> #list > >>>> or throw error? --> > >>>> <#default> Not 2 > >>>> </#switch> > >>>> </#list> > >>>> > >>>> > >>>> P.S. > >>>> It seems that #switch currently doesn't distinguish between #break and > >>>> #continue. As a result, the following treats #continue as if it's a > >> #break, > >>>> rather than skipping to the next item in the #list. > >>>> > >>>> <#list [1,2,3] as item> > >>>> <#switch item> > >>>> <#case 2> > >>>> ${item} > >>>> <#continue> > >>>> <#default> > >>>> ${item} > >>>> </#switch> > >>>> After > >>>> </#list> > >>>> The output is: > >>>> 1 > >>>> After > >>>> 2 > >>>> After > >>>> 3 > >>>> After > >>>> > >>>> Rather than: > >>>> 1 > >>>> After > >>>> 2 > >>>> > >>>> > >>>> --- > >>>> Best regards, > >>>> Simon Hartley > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> On Monday, 5 February 2024 at 23:21:13 GMT, Daniel Dekany < > >>>> [email protected]> wrote: > >>>> > >>>> > >>>> > >>>> > >>>> > >>>> #on is maybe better than #option... I'm not a native english speaker > >>>> though, so I'm nor entirely sure. > >>>> > >>>> Someone else asked what if it's mixed with #case. I would just > disallow > >>>> that. > >>>> > >>>> And of course, with #on (or #option) there would be no fall though at > >> all. > >>>> Since we have multiple values per #on, there's almost no use-case for > >> it. > >>>> > >>>> On Tue, Feb 6, 2024 at 12:11 AM Denis Bredelet > <[email protected] > >>> > >>>> wrote: > >>>> > >>>>> Hello, > >>>>> > >>>>> Good suggestions here. I think #option works well. > >>>>> > >>>>> You could also use #switch … #on … #on … > >>>>> > >>>>> If you want to keep #case and add a modifier, I suggest break=req > (the > >>>>> default, #break is required to exit the #switch) and break=opt > (#break > >>>> only > >>>>> required when you want to exit the #case early). > >>>>> > >>>>> Cheers > >>>>> — Denis. > >>>>> > >>>>>> On 3 Feb 2024, at 21:20, Simon Hartley <[email protected] > >>>> .invalid> > >>>>> wrote: > >>>>>> > >>>>>> If you leave the parent directive as switch, then there would need > to > >>>>> be a decision for what should happen if the user tries to mix option > >> and > >>>>> case in the same switch, i.e. should it "just work"? > >>>>>> > >>>>>> I did remember that JSP used choose/when/otherwise, so your previous > >>>>> suggestion isn't without precedence. #option is as good as any (ahead > >> of > >>>>> #choice and #when ???), but here are some more random words anyway: > >>>> #check, > >>>>> #criterion, #test > >>>>>> > >>>>>> Your idea for multiple values per case seemed like a nice upgrade. > >> What > >>>>> are your thoughts on "values" being expressions as I touched on in > the > >>>>> Future Work section? > >>>>>> > >>>>>> > >>>>>> > >>>>>> > >>>>>> > >>>>>>> On Saturday, 3 February 2024 at 18:19:09 GMT, Daniel Dekany < > >>>>> [email protected]> wrote: > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> <#switch value fallthrough="explicit"> > >>>>>> > >>>>>> With that it's at least clear which behavior we get, but then I > guess > >>>>> it's > >>>>>> too verbose. > >>>>>> > >>>>>>> I would point out that Java switch expressions (not statements) > don't > >>>>>> allow fall-through at all. > >>>>>> > >>>>>> I'm pretty confident that if we support multiple values per #case > (or > >>>>>> whatever it will be called), then fall-through is just not worth the > >>>>>> trouble. > >>>>>> > >>>>>>> Java 21 Pattern Matching syntax > >>>>>> > >>>>>> That's unfortunate, as #when was high on my list. Though it's not in > >>>>> place > >>>>>> of "case" in Java, so it's maybe not that confusing if we have it in > >>>>> place > >>>>>> of #case. Anyway, how about #option then? > >>>>>> > >>>>>> <#switch contact.type> > >>>>>> <#option 'INDIVIDUAL', 'PROXY'> > >>>>>> ... > >>>>>> <#option 'ORGANIZATION'> > >>>>>> ... > >>>>>> <#default> > >>>>>> ... > >>>>>> </#switch> > >>>>>> > >>>>>> > >>>>>> On Sat, Feb 3, 2024 at 6:11 PM Simon Hartley < > [email protected] > >>>>> .invalid> > >>>>>> wrote: > >>>>>> > >>>>>>> Cool. > >>>>>>> > >>>>>>> Just to cover all bases, what about the switch behavior remaining > the > >>>>> same > >>>>>>> unless you opt-in using something like: > >>>>>>> <#switch value fallthrough="explicit"> > >>>>>>> Would you still rather not add the mental overhead of such modal > >>>>> behavior? > >>>>>>> Given your reaction to Go's choice, I assume you'd rather not do > >> that. > >>>>>>> I would point out that Java switch expressions (not statements) > don't > >>>>>>> allow fall-through at all. (There is a compile error if you try to > >> use > >>>>> the > >>>>>>> block syntax that doesn't contain a yield and without the block > >> syntax > >>>>> then > >>>>>>> the yield is implicit.) > >>>>>>> > >>>>>>> If we went the new directive route, should it allow fall-through at > >>>> all? > >>>>>>> > >>>>>>> Naming with a new directive may require care, since when clauses > are > >>>>> part > >>>>>>> of Java's new Java 21 Pattern Matching syntax and so may lead to > >>>> higher > >>>>>>> expectations. > >>>>>>> (see: > >>>>>>> > >>>>> > >>>> > >> > https://docs.oracle.com/en/java/javase/21/language/pattern-matching-switch-expressions-and-statements.html#GUID-A5C220F6-F70A-4FE2-ADB8-3B8883A67E8A > >>>>>>> ) > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> On Saturday, 3 February 2024 at 09:44:38 GMT, Daniel Dekany < > >>>>>>> [email protected]> wrote: > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> I'm not against addressing the core issue, but the only practical > way > >>>> I > >>>>> can > >>>>>>> imagine is with different directive names. > >>>>>>> > >>>>>>> Breaking existing templates is out of the question. > >>>>>>> > >>>>>>> It can't be a configurable behavior either, because then if you > just > >>>>> look > >>>>>>> at a template, you can't be sure what will actually happen. > Consider > >>>>>>> answering SO questions like that, or copy-pasting template snippets > >>>> from > >>>>>>> elsewhere. > >>>>>>> > >>>>>>> What Go did is just wrong, IMAO. They had to find a different name > to > >>>>> avoid > >>>>>>> confusion, like choice/when, or whatever. Same goes for FM. > >>>>>>> > >>>>>>> On Fri, Feb 2, 2024 at 2:38 AM Simon Hartley < > [email protected] > >>>>>>> .invalid> > >>>>>>> wrote: > >>>>>>> > >>>>>>>> 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 > >>> > >>>>>>> > >>>>>>>> > >>>>>>> > >>>>>>> > >>>>>>> -- > >>>>>>> Best regards, > >>>> > >>>>>> > >>>>>>> > >>>>>>> Daniel Dekany > >>>>>>> > >>>>>>> > >>>>>> > >>>>>> -- > >>>>>> Best regards, > >>>>>> Daniel Dekany > >>>>> > >>>> > >>>> > >>>> -- > >>>> Best regards, > >>>> Daniel Dekany > >>>> > >>> > >>> > >>> -- > >>> Best regards, > >>> Daniel Dekany > >> > > > > > > -- > > Best regards, > > Daniel Dekany > -- Best regards, Daniel Dekany
