Proposal: switch expressions
David Koblas
david at koblas.com
Sun Feb 24 16:42:41 UTC 2019
After looking at a bunch of code in our system noted that there are many
cases where our code base has a pattern similar to this:
let category = data.category;
if (category === undefined) {
// Even if Tax is not enabled, we have defaults for incomeCode
switch (session.merchant.settings.tax.incomeCode) {
case TaxIncomeCode.RENTS_14:
category = PaymentCategory.RENT;
break;
case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
category = PaymentCategory.SERVICES;
break;
case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17:
category = PaymentCategory.SERVICES;
break;
}
}
I also bumped into a block of go code that also implemented similar
patterns, which really demonstrated to me that there while you could go
crazy with triary nesting there should be a better way. Looked at the
pattern matching proposal and while could possibly help looked like it
was overkill for the typical use case that I'm seeing. The most relevant
example I noted was switch expressions from Java. When applied to this
problem really create a simple result:
const category = data.category || switch (setting.incomeCode) {
case TaxIncomeCode.RENTS_14 => PaymentCategory.RENT;
case TaxIncomeCode.ROYALTIES_COPYRIGHTS_12 =>
PaymentCategory.ROYALTIES;
case TaxIncomeCode.INDEPENDENT_PERSONAL_SERVICE_17 =>
PaymentCategory.SERVICES;
default => PaymentCategory.OTHER;
}
Note; the instead of using the '->' as Java, continue to use => and with
the understanding that the right hand side is fundamentally function.
So similar things to this are natural, note this proposal should remove
"fall through" breaks and allow for multiple cases as such.
const quarter = switch (foo) {
case "Jan", "Feb", "Mar" => "Q1";
case "Apr", "May", "Jun" => "Q2";
case "Jul", "Aug", "Sep" => "Q3";
case "Oct", "Nov", "Dec" => { return "Q4" };
default => { throw new Error("Invalid Month") };
}
Also compared this to the do expression proposal, it also provides a
substantial simplification, but in a way that is more consistent with
the existing language. In one of their examples they provide an example
of the Redux reducer
https://redux.js.org/basics/reducers#splitting-reducers -- this would be
a switch expression implementation.
function todoApp(state = initialState, action) => switch
(action.type) {
case SET_VISIBILITY_FILTER => { ...state, visibilityFilter:
action.filter };
case ADD_TODO => {
...state, todos: [
...state.todos,
{
text: action.text,
completed: false
}
]
};
case TOGGLE_TODO => {
...state,
todos: state.todos.map((todo, index) => (index ===
action.index) ? { ...todo, completed: !todo.completed } : todo)
};
default => state;
}
More information about the es-discuss
mailing list