Learning Functional Programming: Managing Code Complexity by Thinking Functionally