1. Overview
In this chapter, we provide an outline of the course, along with a brief motivation and key learning outcomes.
1.1. Course Information
1.2. Motivation
There are a number of reasons why you would want to study programming languages. To name a few:
Knowing several programming paradigms will help you think about more problems in better ways.
Knowing several programming languages will help you implement your solutions in better ways.
The subject matter is exciting and intellectually challenging.
Increasing numbers of local, national, and global employers love it!
1.3. Key learning outcomes
We deliberately chose the learning outcomes for this course to complement other courses in your computer science or software engineering curriculum. Upon entering this course, you will already be familiar with the imperative and object-oriented paradigms, coming from languages such as Java, C++, C#, or Python. Most likely, you will also be familiar with basic machine architecture and memory management using C or C++.
In this course, we will pursue two overarching learning outcomes and three more specific ones:
an overview of programming paradigms (see Context and Background, Other Important Programming Paradigms)
an understanding of the programming language design space (see Context and Background, Appendix: Programming Language Design Principles)
proficiency in functional programming (see The Functional Programming Paradigm)
an understanding of program representation and interpretation/execution (see Program Representation and Interpretation)
basic competence in concurrent programming (see The Concurrent Programming Paradigm)
Given the widespread availability in multi-core hardware ranging from mobile devices to enterprise servers, there is a growing interest in programming paradigms and techniques that will take advantage of this hardware. Functional programming, which de-emphasizes mutable state, in conjunction with suitable concurrency constructs, is particularly useful. We will also “look under the hood” by studying how to represent programs and interpret, execute, or otherwise process those representations.
1.4. Resources
For paradigm-specific reading lists and recommended texts, see Appendix: Resources.
You might also find the following general resources useful as starting points:
Presentation by Martin Odersky: Scala with Style (YouTube)
Interview with Simon Peyton-Jones on Functional Programming and Haskell (SE Radio audio podcast)
Presentation by Läufer, Thiruvathukal, and Kaylor: The Promise of Statically Typed Functional Programming (visual presentation)
The presentation covers three main arguments: the promise of statically typed functional programming for program correctness; the broader context of modern multi-core hardware and cloud computing; and a comparison of languages (Scala, Haskell, Clojure) in this light.
1.5. Course outline
Here is a more detailed course outline (subject to revision).
The course begins with context and background (software engineering practices, language paradigms), then surveys the major paradigms in depth: imperative, object-oriented, functional, logic, and concurrent. We then “look under the hood” at program representation and interpretation. A final chapter surveys additional paradigms (reactive, dataflow, AOP) before concluding with cross-cutting principles.
business and software engineering contexts (1 week)
software requirements
functional requirements
nonfunctional requirements
development process
testing
refactoring
automation
design principles and patterns
separation of concerns
parametricity
SOLID
GoF/POSA
imperative and object-oriented programming (2 weeks)
console applications
constant-space complexity
logging
domain modeling
using traits for modularity and dependency injection
functional programming (4 weeks)
defining algebraic data types
scalars: enumerations
sublinear structures: numbers, option
linear structures: lists, maps
nonlinear structures: trees
implementing behaviors on algebraic data types
pattern matching
recursion
higher-order functions
predefined types and their behaviors
recursion patterns
higher-kinded types
programming language representation and interpretation/execution (4 weeks)
language design space
scanners (lexical analyzers)
parsers (syntax analyzers)
interpreters and compilers
domain-specific languages
concurrent and parallel programming (3 weeks)
parallel collections
futures and promises
progress reporting and cancelation
asynchronous programming/reactive extensions (Rx)
advanced mechanisms
explicit threads
actors
software-transactional memory
task-parallel library
functional data structures
1.6. Bloom’s taxonomy
The letters refer to the successive levels of learning from the cognitive domain of Bloom’s taxonomy:
K: know/remember the term
C: comprehend/understand the concept
A: apply the technique
analyze/evaluate/create (advanced levels)
Learning outcome |
Bloom level(s) |
|---|---|
Overview of programming paradigms |
K, C |
Understanding of the PL design space |
K, C |
Proficiency in functional programming |
C, A |
Understanding of program representation and interpretation |
C, A |
Basic competence in concurrent programming |
C, A |