The primary reason is when you don't want to run the code directly, but rather, want to inspect it. This can be for any number of reasons:
- Mapping the code to a different environment (ie. C# code to SQL in Entity Framework)
- Replacing parts of the code in runtime (dynamic programming or even plain DRY techniques)
- Code validation (very useful when emulating scripting or when doing analysis)
- Serialization - expressions can be serialized rather easily and safely, delegates can't
- Strongly-typed safety on things that aren't inherently strongly-typed, and exploiting compiler checks even though you're doing dynamic calls in runtime (ASP.NET MVC 5 with Razor is a nice example)