Using programming language concepts to teach general thinking skills

ion is a necessary process that most people engage in unconsciously. But an inappropriate abstraction can be problematic — if one discards important information during the process of abstraction, they can limit their thinking, acquire blind spots, or come to the wrong conclusion. The explicit, overt, and precise nature of abstraction in programming languages can help students develop a general framework that they can use to improve their reasoning in other fields. This framework will help students perceive and understand both the need for abstraction and the potential problems that are an inevitable consequence of its use. Building on their experience with abstraction in programming languages, they will also be more able to see, understand, and criticize the implicit abstractions that they and others make in other fields where the abstractions are much less obvious and potentially even part of a standard and otherwise unquestioned approach. If students learn to apply a process of seeking out abstractions, understanding the resulting limitations, then, when appropriate, developing new abstractions that remove inappropriate limitations, they will be better able to understand how to innovate around shortcomings and challenge ways of thinking that have, over time, become limited or even counterproductive. When applied by someone with a sufficient command of the process, it can even become a mechanism for generating insights, creativity, and productive new directions upon demand. 4.2 Pragmatic Applications Computer science professionals must deal with abstractions on a daily basis. Knowledge of programming language abstractions and how to use them is a prerequisite for functioning effectively in any professional environment. Moreover, many computer science professionals spend much of their time designing abstracts. A deeper understanding of abstractions in general can help them design more effective abstractions. 5. Potential Teaching Approaches The field of programming languages is rich enough to support many productive teaching approaches. I outline two such approaches, but recognize that there are other approaches that may be equally or even more productive. Both of the approaches start with software development activities. One advantage of this starting point is that it leverages the immediate feedback and precision that interacting with a computer provides and requires, which makes the concepts obvious and accessible. It is also possible to structure the software development activities to emphasize specific skills or approaches that students can immediately use in a professional software development career. It is also possible to take a more theoretical approach that starts with mathematical modelling or analysis activities. In either case, however, the most important part of the educational experience is reflecting on the concepts that the specific activities illustrate. This reflection is crucial to enabling students to generalize the concepts to apply them productively in different contexts, which is the most important and valuable lesson of the course. One way to incorporate this reflection into the course is to require students to perform additional assignments (typically in essay form) that demonstrate the application of the acquired concepts to a field outside of programming languages. 5.1 A Domain-Specific Language This approach would organize the course around designing and implementing a language for computations in a particular domain. The course would be composed of several stages. The first would be to develop and understanding of the basic concepts in the domain. The second would be to design a language that supported the concepts explicitly. The third would be to implement the language. Finally, the students would implement several computations in the language. Successfully developing the engineering artifacts would be only part of the educational process. The arguably more important part would be using the engineering experience as a foundation for reflecting on the different concepts. To this end students would write essays focusing on how their experiences relate to multiple perspectives, automation and translation, and abstraction in other contexts. Ideally, students would understand that the concepts in the domain-specific language were different from the concepts in general-purpose languages (the course would assume that previous introductory courses have already provided the students with knowledge of at least one such language) and that providing these concepts explicitly in the language provides a more productive perspective for computations in the domain than the perspective from general-purpose languages. Students would also understand that making the domain concepts explicit in the language shapes how they formulate and solve problems in the domain. They would also understand how to generalize this example to understand that other perspectives would be useful in other domains, and indeed that some domains would be complex enough to justify the use of multiple perspectives. Finally, they would understand that it is possible (although potentially not ideal) to explicitly adopt a given perspective during the engineering of the system even though one may use a general-purpose language instead of a domain-specific language. Students would address the automation and translation concepts as part of the implementation of the domainspecific language. They would understand that certain aspects of the implementation were automated by the implementation of the domain-specific language, and that these aspects would instead be performed by the human developer if the system were built in a general-purpose language. They would also understand how to generalize the basic concepts illustrated in this exercise to obtain an understanding of how automating tasks can make people more productive, that automation requires thinking about the general case as opposed to any specific single problem at hand, and that some tasks are still better left to humans. The implementation of the domain-specific language would provide a concrete example of the power of translation in packaging automation for effective use by developers. Ideally, students would be able to build on this experience to become more aware of the potential benefits and drawbacks of automation, more able to use it effectively in their careers, and to better understand what kind of tasks are best automated and what kind of tasks should be done by humans. One way to address abstraction would be to develop a type system for the domain-specific language. Ideally, the students would formulate a formal connection between the semantics of the full language and the abstract semantics that the type system induces. They would understand the purposeful discarding of information involved in the abstraction and the benefits and drawbacks of discarding the information. They would be able to generalize the experience to formulate frameworks for abstraction in other fields, be able to understand the benefits and drawbacks of using abstractions, and be prepared to identify (and if appropriate discard) otherwise implicit abstractions present in a variety of fields. 5.2 Different Language Paradigm Instead of developing a domain-specific language, one could instead start with an existing language whose basic approach and concepts differ substantially from those of conventional programming languages. In this case, going through the exercise would help students understand the importance of different perspectives and how perspectives shape the understanding and engineering process. The automation and translation aspect could be covered by studying the implementation of the logic programming language. One productive approach could be to ask the students to implement a simple language based on the core concepts of logic programming. Developing an analysis for the language, either to support efficient implementation or to check certain desirable properties, could be an effective way to introduce the concept of abstraction. The important point here is not that logic programming is necessarily valuable in and of itself or that students will necessarily use the specific concepts in logic programming in their careers. Rather, the use of logic programming in an appropriately structured course (like the use of other nonmainstream approaches) can illustrate general concepts and make those concepts accessible to students in an immediate and concrete way.