-
Notifications
You must be signed in to change notification settings - Fork 147
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default case in switch #923
Comments
That is my understanding, yes: it should fall back to the IMHO no error should be implicitly thrown if no case matches, as this can be explicitly done by author if - and only if - need be, just like in all languages I know of.
IMHO, no: it was like that in previous versions, but it was more restrictive than anything afaik. Think of a switch with two cases: one that defines a condition, and is called "yes", for example, and a second that is the default's. Forcing the latter to be called "default" is counter intuitive, as you would rather call it "no". Don't you agree? This is the option that provides imo the biggest flexibility and freedom to authors. Related to #627 |
Yeah the implicit flow control of the spec is quite different from a lot of other workflow engines centered around state machines, where no outgoing connection usually means an error. Your answer makes sense here 👍 Do we fear that this might be a cause for common bugs? As any programmer knows: switch fallthrough is neat but somehow always comes back to bite you 😅 (many linters flag switch fallthrough or missing default cases)
That makes sense, my thinking behind it was that maybe it would help to standardise workflow definitions a bit and thus help authors & readers to quickly identify the default case. But I have no strong opinions here and think your point is very convincing |
I have a slightly different take on the matter. In my opinion, we should enforce
It doesn't indeed because it's not really a case. It's been introduced to mimic what we have while programming (and it doesn't really make sense. I'll come to it later*)
I understand the logic, and it's quite valid, but IMO, it introduces confusion. The term always implies that even if another case is matched, then the default will be too (it won't, I know, I'll come to it later*).
I agree. The switch task is just another task, it still complies with the basic definition of a task.
* I think our switch is slightly different than a regular switch in programming. I'm not sure it's clear enough in the specification but only one match is possible (edit: to be more precises, only the first matching case will be executed, even if more than one match). Therefore, technically, it's impossible to "fall-through". Given the task: switchTask:
switch:
- myFirstCase:
when: . == "foo"
then: something
- mySecondCase:
when: . == "bar"
then: somethingElse
# - myDefaultCase:
# then: defaultBehavior The pseudo-code representation of switch task would be: function switchTask(input) {
switch (input) {
case "foo": // myFirstCase
return goTo('something');
case "bar": // mySecondCase
return goTo('somethingElse');
// default: // myDefaultCase
// return goTo('defaultBehavior');
}
return gotoNext(); // <-- It's the de facto default, as per specification. If "myDefaultCase" was enabled, it would never be reached but still be "defined".
} Each case returns, there is not possible fall-through. I assume by fall-through you mean the use-case where none of the case matched (e.g. input = 42). Then, I think it's another argument for removing the optional
That's the only argument to keep a default case, and I don't think it's a very strong one. It is like tasks we opinionatedly decided should be named. The "feature" resides in switchTask:
switch:
- . == "foo":
label: myFirstCase
then: something
- . == "bar":
then: somethingElse It's very ugly, I think we'll all agree. My point is it still works, because the mandatory pieces of information are the condition and the transition. The name is just some metadata to improve the aesthetic and readability of the workflow. Keeping the default case "just" so we can name it feels like a weak argument. I would suggest to rather introduce a new property at the switch task level, like askConsent:
switch:
- yes:
when: . == true
then: continue
labeled: no
then: cancel or the other way around: askConsent:
switch:
- no:
when: . == true
then: cancel
labeled: yes So sum up:
Cons
|
I disagree. Naming cases is critical for (non author) user feedback and for cosmetic purpose: you do not want to force a user to understand the expression of the when to understand what the case does.
In you sample, not commenting the default case would result in the exact same behavior than the one you want to avoid, which is perfectly valid in all languages I know of. At worst, the linter would raise a warning for the last return saying that it won't ever be reached.
It's not just ugly, it's invalid: you cannot use such characters in a propert name.
It is consistent imo. I dont see why having the possibility to add a possible override for aestetic reason would make it otherwise.
The current solution does not add any complexity to the schema imho. It's just one single property, which could btw be removed and be instead considered a DSL validation responsibility.
I personally dont see the potential confusion here. Either you want the ability to name the default behavior and you use the whenless case, either you dont and use the task's then.
I disagree. It cannot be mitigated in any non-trick looking fashion, as you demonstrated, whereas the current behavior is clean and intuitive imho. Bottom line is that, as said in previous comment, doing what you suggest would be a regression, and would be confusing/less readable to users with a non technical background. On a side note, I have a strong - yet personal, of course - aversion for the mitigation solutions you proposed, which I think add complexity and make the overall switch heavier and uglier. I dont see how a prop such as "labeled" or whatever would be intuitively associated to the task's then |
@ricardozanini @fjtirado @matthias-pichler-warrify What do you guys think? I think we need your input to determine whether or not we should proceed with potential changes. A good tiebreaker, if need be, would be to present alternatives to non-technical people and gather their feedback. |
I like @JBBianchi proposal (remove "default") |
Let me describe the case I have in mind
There is not default there, I only want to increase salary to my friends and fire the ones that has insulted me. And congratulate christmas to everyone |
@fjtirado I'm not sure I understand your sample: a matching case will transition, therefore won't ever fire the then, which will only be matched if nor increaseSalary or fireEmployee match. In other words, you'll only congratulate everyone if you don't promote or fire someone. There is no way to actually transition to a case's then, then after the whole chain is resolved, execute the tasks's then. As for the naming, the then contains the name of the task to then perform, and is in no way related to the name of the case. Imagine a switch with yes/no cases, yes could transition to credit, no could transition to debit. |
hmmm. It would be nice if there is way to tell fireHim and doubleSalary to "return" to the "branching" task so sendChristmasGreentToAllEmployees is executed always. |
@cdavernas yes, I just realized.
What happens after issue is escalated? |
@fjtirado you can do that by configuring the tasks referenced by your cases to then transition to greet. Doing it in the switch is imho dangerous and confusing: whereas it is a simple branching, your proposal would transform it on a kind of subflow. |
Because you did not set the |
@cdavernas Ok, that was I thought, is that intended? It wont be safer to define the task that raise the error the latter? |
@fjtirado this is up to you, and has imho nothing to do with the switch task, but is rather related to how you want to define/control your flow. Setting the In your example, because you did not specify flow control, all cases aside from |
@cdavernas so, rewriting previos one
|
After digging in the DSL, the previous example can be written this way (with not switch)
However note that, being picky, fireemployee should not be checked if salary has been increased. Maybe we need to work on that. |
Wouldn't setting the Afaik it would mean that if (and only if) said task is executed, meaning that the if is matched, then it transitions to greeting everyone. |
Sure, it will do, but if later on we decide that we want |
Anyway, I am deviating (as always) from the original issue, with the new knowledge I just acquired, I would say the discussion is between having a |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
What would you like to be added:
Currently the DSL states for the switch case that:
when
This wording implies that the default case does not follow ordering because it is only
matched by default if no other case match
therefore these two would be equivalent:
and
I think this is a bit ambiguous and would change the wording to something like:
This would then mean that the only logical place to put a default case would be at the end. Interested in what you folks think.
This is currently not validated by the schema.
I think it could beIt is doable withcontains
. This schema ensures only one case has nowhen
The DSL does not specify what happens when no case matches. Does it fall through to the next task? (I don't think this should be the intended behavior) Or which error is raised?
And my last question: would it make sense to enforce that the default case is named
default
?Why is this needed:
The text was updated successfully, but these errors were encountered: