I tried to avoid the code duplicating, so it became more compact and perhaps less readable. Also I added reporting about the packages to upgrade: I thought as they are going to be replaced by the packages to install, it is ok to add “(removed)” there. So an output should look like this (assuming "file-5.17" and "guile-2.0.9" are installed and are being upgraded): The following packages will be upgraded (removed): file-5.17 out /gnu/store/... guile-2.0.9 out /gnu/store/... The following packages will be installed: file-5.18 out guile-2.0.11 out