ну вот тут, например, используется переменная key из внешнего скоупа в редюсере...
по определению получается функция не чистая (замыкание), но по факту за пределами цикла всё чисто
на первый взгляд кажется что у тебя утрированный пример, но на самом деле нет: если newShape имеет геттер на поле key то тот кто его установил имеет возможность упасть или начать иначе проявлять себя, по этой причине системы построенные со сложными гетерами часто ненадёжны: если может упасть даже чтение поля то всё плохо