Theories for reasoning about programs with effects initially focused on basic manipulation of lists and other mutable data. The next challenge was to consider higher-order programming, adding functions as first class objects to mutable data. Reasoning about actors added the challenge of dealing with distributed open systems of entities interacting asynchronously. The advent of cyber-physical agents introduces the need to consider uncertainty, faults, physical as well as logical effects. In addition cyber-physical agents have sensors and actuators giving rise to a much richer class of effects with broader scope: think of self-driving cars, autonomous drones, or smart medical devices. This paper gives a retrospective on reasoning about effects highlighting key principles and techniques and closing with challenges for future work.