Take the following:
@action(reads=['input_var'], writes=['output_var'])
def simple_action(state: State) -> tuple[dict, State]:
output_var = _compute(state["input_var"])
result = {"output_var" : output_var}
return result, state.update(**result)
# or
return result, state.append(**result)
This is just a lot of boiler plate -- you have to:
- Compute the result
- Store it in a variable
- return it
- Apply a state update using it
Note most people will probably write it like this:
@action(reads=['input_var'], writes=['output_var', 'output_var_list'])
def simple_action(state: State) -> tuple[dict, State]:
output_var = _compute(state["input_var"])
return {"output_var" : output_var}, state.update(output_var=output_var).append(output_var_list=output_var)
Which is correct, but kind of strange. This is due to the oddity of the "single-step" action. That said, if we want these as simple python functions, then we don't really need the result. Just inspecting the state delta will do it... In fact, when we have the layering, we can think of the state delta as the result.
So, what if we just didn't have intermediate results for certain simple state updates:
@action(reads=['input_var'], writes=['output_var'])
def simple_action(state: State) -> State:
output_var = _compute(state['input_var'])
return state.update(output_var=output_var).append(output_var_list=output_var)
We would determine which we use either based on the annotation or the return type, nd the user would do this knowing that they wouldn't have access to intermediate results in the UI...
Alternatively, we could have them only use the result, and we auto-update the state...
@action(
reads=['input_var'],
writes=[
update(output_var='output_var'),
append(output_var_list='output_var')
]
)
def simple_action(state: State) -> dict:
return {"output_var" : _compute(state['input_var'])}
Having update
as a separate function is just one approach, could have increment
and append
, or have the default be update
More ideas (in this case I'm adding output_var_list
to illustrate append
@action(reads=['input_var'], writes=[update('output_var'), append('output_var_list')])
@action(reads=['input_var'], writes=['output_var', append('output_var_list')]
@action(reads=['input_var'], updates=['output_var'], appends=['output_var_list'])
@action(
reads=['input_var'],
writes=['output_var', 'output_var_list'],
update=lambda result: state.update(output_var=result['output_var']).append(output_var_list=result['output_var'])
)