So, incf, which is CL's +=, could be defined as
(defmacro (incf lexpr val) `(setf ,lexpr (+ ,lexpr val))
which would evaluate "lexpr" both as a place to put the new value in and as an expression to get the old value out.
If you wanted to do that in terms of purely-functional monad application, it gets a bit hairier... Basically, you've got things like "+=" which are mutators (i.e. functions Int->Int). And you've got places, which either (i) take an X mutator and turn it into a mutator for Y, or (ii) take a Y and return an X (accessor).
In your example,
list_of_objects[index].attr = 'abc'
would mean that you take a "constant value" mutator that takes some string and returns "abc" and turn it first into a mutator that changes the .attr value of something ... to something that changes the .attr value of index [index] of the list_of_objects member of the current data.
Why would that kind of functional style be useful? Basically, because you could write something like a Python program that still allows for search/nondeterminism/backtracking etc.
Some of the weirdness I see in Mutagen seems to come from a partial (or just differing) understanding of how Python and Haskell, respectively, do things. Shoot me a PM if you want to discuss more.