im not exactly sure about that but i know that at least for integers there are atomic update commands and that for strings there are atomic append commands.
so for this you would really just want to do: APPEND foo d
or for more complex situations you could do use WATCH instead of MULTI so that you can get the intermediate results. so for your example:
WATCH foo
GET foo ->value
//calculate new_value
MULTI
SET foo new_value
EXEC
now if at any other operation (not part of this connection) modifies foo then the transaction will be aborted.
GET foo -> value
//application logic to update value
GETSET foo new_value ->prev
then prev will contain the value of foo at the time it was set, so you can then use application logic to roll back or redo the transaction