Logical Foundations of Functional Programming