more generic loop