This paper comprehensively reviews the fundamental concepts of differentiable programming. Focusing on the recent advances in artificial intelligence, including large-scale models, massive datasets, high-performance hardware, and the transformative power of differentiable programming, we introduce differentiable programming, a new programming paradigm that enables end-to-end differentiation of complex computer programs (including control flow and data structures). Drawing on several areas of computer science and applied mathematics, including automatic differentiation, graphical models, optimization, and statistics, we adopt two major perspectives, optimization and probability, and present a clear analogy between the two perspectives. Beyond simply differentiating programs, we emphasize the thoughtful design of programs for differentiation, and by making programs differentiable, we provide a method for quantifying the uncertainty associated with the program output by introducing a probability distribution over the program execution.