I was reading about XMF (which is an ExtensibleProgrammingLanguage). Among its described features is 'FirstClassUndo'ability.
'Undo' is a very valuable feature for human interfaces - where possible, it should be used instead of warnings. Of course, not all things can be undone (you can't 'undo' lost time, lost opportunity, hurtful words (or sent message of any sort), a sped arrow (or bullet)). But, when working in the context of data management, it would be very nice to have this feature common across languages and across as many actions as is feasible.
Note that 'Undo' is not the same as 'uncommitted'. For transactions and databases, 'undo' means the ability to roll back a particular transform after it has become part of the database, which means (essentially) keeping one or more 'undo' stacks.
Therefore, ExtensibleProgrammingLanguage would make it easy to avoid creating SoftwareThatPunishesTheUser
XMF isn't the only ExtensibleProgrammingLanguage (I added a note on that page to explain). And being extensible is not necessary for FirstClassUndo. Those two capabilities are very much orthogonal.
FirstClassUndo, however, would make it easier to avoid creating SoftwareThatPunishesTheUser.
Example from XMF:
let v = Vector(1) in format(stdout,"v before update : ~S~%",Seq{v}); @Undoable v.put(0,"Frank") end; format(stdout,"v after update : ~S~%",Seq{v}); xmf.undoEngine().undo(); format(stdout,"v after undo : ~S~%",Seq{v}); xmf.undoEngine().redo(); format(stdout,"v after redo : ~S~%",Seq{v}) end;This program gives rise to the following trace:
v before update : Vector{null} v after update : Vector{Frank} v after undo : Vector{null} v after redo : Vector{Frank} 0:0:0:16 ms ] true