ISTE Home
About ISTE
Advocacy
Educator Resources
Membership
Affiliates
Awards & Recognition
ISTE 100
Join or Renew
Member Campaigns
Member Central
Member Networking
My Profile
Podcasts
Premium
Special Interest Groups
SIG Newsletter
Join a SIG
Join SIGCT
SIGCT Officers
Journal for Computing Teachers (JCT)
JCSE Online - Journal of Computer Science Education
Past Issues
2005-2006
2004-2005
May 2005
March 2005
December 2004
2003-2004
2002-2003
2001-2002
Submission Guidelines
SIGCT & NCWIT
SIG Directory
SIG Projects & Archives
SIG Wikis, Listserves & Ning
Volunteer
ISTE 2010
NETS
Career Center
News & Events
Professional Development
Publications
Research
Store

Printer Friendly
Members Only Members Only

Early Software Design Experience Through Computer Game Programming in the Functional Paradigm

Tamar Paz
Technion, Israel Institute of Technology
Orna Muller
Tel-Aviv University, Israel

Abstract

Programming projects in the functional paradigm enable beginning students of computer science (CS) in high school to experience the whole process of developing a complex program in a relatively short time. In the course of project building the students practice the various stages of software development, such as system requirements analysis, top-down design, function definition, testing, documentation, and the design of a user-friendly interface, all while working in a team. This early exposure to the stages of program development makes the concepts and principles presented more real and meaningful when brought up later in more advanced CS courses. This article was written after seven years' experience in teaching a functional programming course in high schools in Israel, where students have successfully coped with developing, from scratch, programming projects taken from the field of artificial intelligence. This experience demonstrates that the functional paradigm is an excellent environment for developing a project by beginning students.

1 Introduction

The computer science curriculum in the Israeli high school system includes five modules (Gal-Ezer, Beeri, Harel & Yehudai, 1995). Each module consists of 90 academic hours. The first two modules constitute a course, Computer Science Fundamentals, taught in a procedural environment. The third module presents an additional programming paradigm and its main goal is to expose students to a significantly different approach to problem solving than that of the procedural paradigm. The fourth module focuses on data structures and software design and the fifth module is a theoretical unit (such as computational models). In this article we focus on one of the alternatives of the third module—a functional programming course.

The selected programming environment for teaching this module is DrScheme, which was developed at Rice University in Texas (Felleisen, Findler, Flatt, & Krishnamuethi, 2001)1. The main topics introduced in the course include elementary language functions, the two main data types (an atom and a list), function definition, conditionals, and recursion (Leron, Lapidit, Levy & Paz, 1999).

The course lasts 90 hours in one academic year of which about 60 hours are dedicated to introducing and practicing the above language features. The last 30 hours are devoted to writing a final project required for getting a credit for the course. However, gradual preparation for the project is integrated in the first part of the course, as will be described in Section 4. The majority of students choose to develop a game, usually a card game like Taki or Poker, or a board game like Tic-Tac-Toe, Battleships, Othello, Mancala, Mine Sweeper, Monopoly, Four in a Line, Lotto, Dominoes, and others.

In the following sections we first discuss why the functional paradigm is particularly well suited for developing a large-scale project by beginners. Later, we illustrate how students experience the various stages of software development, while acquiring basic principles of computer science.

2 The Functional Paradigm as a Well Suited Environment for Developing Projects by Beginning Students

The functional environment facilitates the development of a large and complex project by beginning students, since they are able to learn the language’s basic grammar in a relatively short time. This allows the major part of the course to be devoted to problem solving and program development practice.

2.1 Minimal Syntax

The functional paradigm relies on a small set of syntactic rules. All of the expressions in the environment have a uniform structure. Parentheses constitute the only punctuation mark, and two basic data types (an atom and a list2) are sufficient for describing complex data structures and non-linear structures like trees (Abelson Sussman & Sussman, 1996; Felleisen et al., 2001).

The uniformity of representation of the different data types simplifies the implementation of various operations on them (such as searching for an item). The ease of representation is achieved thanks to three main characteristics of a list: flexibility in the number of items (the number of items in a list, when passed as an argument in a function-call, may vary at different calls of the function), combining of different data types (a data list may simultaneously contain items of different types, including items which are lists themselves), and simple access to each item (through a library function). A list, therefore, is a flexible data type that has the advantages of an array, a record, and a linked list. Furthermore, basic operations like adding an item to a list or merging lists are simple to implement.

During the first part of the course, students become familiar with the elementary functions of the environment and the basic data types, and learn how to define new functions. This basic knowledge enables them, after only 12-15 academic hours, to develop from scratch a program for a relatively complex task such as checking if a given Tic-Tac-Toe board is a winning board.

2.2 Function Composition as a Basic Operation

The functional environment, as presented to the learners of the course, encourages decomposition of a task into sub-tasks and writing a function for solving each sub-task. That is to say, the environment encourages thinking and writing of independent modules that solve specific problems.

Function composition, a mechanism in which the returned values of one function serves as input for another function, is a major tool in the functional paradigm. A program is built by means of composing functions as opposed to sequencing actions in the procedural programming. Although the environment allows direct assignments3, the course developers decided to hide this capability from the students (Leron et al., 1999). Use of assignment commands would have permitted students to continue their procedural routine (i.e., giving names to intermediate results by using assignment commands and storing the results in variables) and to program according to familiar algorithms from the procedural environment (Paz, 2003).

2.3 Abstraction as a Tool in Organization and Control of Complexity

Abstraction is an important tool in organization and control of complexity both in mathematics and in computer science. Developing a complex program entails a process of abstraction at the stage of dividing the task into sub-tasks, as well as at the stage of defining data representation. Control of complexity is achieved by temporarily disregarding details and by developing "building blocks" that are appropriate for the problem, as well as for the programmer (Leron, 1987; Abelson et al., 1996).

In the programming of a complex task, the problem-solver builds a metaphoric "abstraction barrier" that separates the handling of the task into two nearly independent sub-tasks: above the barrier and below the barrier. The "above the barrier" sub-task deals with finding a solution to the original problem in terms of the "building blocks" that were selected. The "below the barrier" sub-task deals with the details of implementing these "building blocks" in the given programming language (Leron, 1987).

The functional paradigm, as presented to the learners, constantly imposes throughout the development process building abstraction barriers, defining "building blocks", employing them (above the barrier), and implementing them (below the barrier). This experience prepares the students for the abstraction necessary when developing a program for solving complex problems in other paradigms as well.

2.4 Interactive and Friendly Programming Environment

The functional programming environment allows for calling each function independently, and not only as part of a whole program. Therefore, students can explore new functions or modules by directly testing them with different inputs and performing a single function debugging. The visual support provided by the editor and the friendly and clear error messages also support modular writing and debugging.

2.5 "Soft" Exposure to Recursion

Another contribution of learning the functional paradigm at an early stage is related to the “soft” exposure to recursion. The only repetition structure to which students are exposed is recursion. Therefore, from the first stages of familiarization with the paradigm, they are required to cope with writing recursive functions. Recursion is considered a powerful technique in problem-solving and for handling complex data structures. At the same time, many studies have revealed that recursion is one of the most difficult concepts for comprehension, instruction, and learning, especially for beginning programmers (Leron, 1988; Mann, Linn & Clancy, 1994; Segal, 1995). The functional paradigm facilitates "soft" entry into the topic of recursion, thanks to the uniform structure of the functions which the students write, and the relative ease with which they can build recursive functions and follow their execution.

3 Experiencing the Program Development Stages

While developing a project in the functional programming course, students go through the same stages that are undergone by software developers (as for example, described in Pressman, 2001).

3.1 Software Specifications

At the first stage of developing their project students choose, according to their personal preferences, the kind of program they wish to develop. If they choose to develop a game, they decide at this point what type of game it will be: Will the program arrange a game between two human players, or between a human player and the computer? What will be the rules of the game? Will the computer's moves (as a player) be chosen randomly or according to some strategy? And so on.

This phase is compatible with the software specification analysis stage in which the requirements of the system to be built are defined. The requirements should take into consideration different kinds of factors including the system's input data and the limitations of the development timetable. At this time, students need to describe the main tasks to be performed (the "what"), without the task implementation (the "how"). Clear and detailed specifications help also at later stages like testing and evaluation of meeting the initial requirements.

3.2 Decomposition into Sub-tasks

After defining the requirements for the complete program, students try to identify smaller tasks within the larger task. A schematic description of the game's algorithm helps in identifying the major sub-tasks required. When developing a game, preliminary sub-tasks are likely to be: building a game board or a pack of cards, shuffling and dealing cards, checking if a win was achieved, etc. Each task undergoes additional, more refined partitioning (by stepwise refinement) to the level of identifying actions that can be implemented by separate functions (Wirth, 1971).

Students get an opportunity for a hands-on experience in a top-down design, one of the main strategies employed to cope with the complexity of a problem. Moreover, decomposition into sub-tasks is the first step in building a modular program. Modularity is a central principle in software engineering, and has significant implications on the next steps of development. Students experience its importance in the context of team work, testing and debugging, and program extension.

3.3 Data Representation

Software design also entails choosing the main structures in which the data will be organized. Different possible representations are defined and then compared. Students realize that they need to take into early consideration the influence of data representation on the ease of implementing the pre-defined operations. The issue of data representation and its effect on later steps of development are raised and discussed.

3.4 Coding and Integration

At this stage the previously planned modules are implemented by writing functions’ code. Students are likely to make use of the functions they had written during earlier stages of the course, when building general tools for handling different tasks such as searching for an item in a list, updating a list, or constructing a list of random numbers. While using code written and checked previously, students practice the important principle of reuse. Students appreciate its benefits in saving effort and being supported by modularity and general functions.

Coding the separate modules is followed by their integration into a complete game. The code integration stage requires a gradual, bottom-up process of joining the various modules that were developed until a complete product is achieved. This stage poses a significant challenge to the students. The composition process is likely to include, for instance, the interleaving of the human-player and the computer moves that were implemented in separate modules. Integration often requires writing additional auxiliary functions. Preparation for coping with the composition stage is done in prior stages of the course by solving a series of problems of increasing complexity.

3.5 Testing and Debugging

Since a functional environment facilitates immediate checking of each functional module after its development, testing, in fact, accompanies all stages of development. Particular attention is given to testing improper inputs by the user ("the player").

The importance of modular writing is manifested again, since it is made apparent that when the role of each module is defined and clear, it is easier to locate the module responsible for an observed problem. The smallest possible dependency between modules facilitates the correction of an error in one module, with no chain-effect on other modules.

3.6 Team Work

Projects are developed in groups of 2-3 students. While some stages, like planning, are done in a team, the implementation of modules is done in parallel by the different team members. The development in a team framework clearly demonstrates the advantages of precisely pre-defining the interfaces of modules, and of task partition into modules with minimal dependency between them.

3.7 Documentation

Concise and clear documentation of the program is a highly important component in its development. The students realize the importance of documentation when they are asked, as part of the project requirements, to master the modules that were developed by other members of the team.

A project portfolio, which the students attach to the developed software they present, documents various aspects of their work. Documentation includes justification for the chosen data structures, guidelines for operating the game, its description and rules, documentation of each function and module (role, passed parameters, returned value, assumptions taken, etc.), program outline, and also some reflection on their personal and team experiences.

3.8 Extension

The capability of extending the game to achieve more complex tasks may be evident by the possibility to introduce changes in the developed project. For instance, to allow variation in the size of the game board, to change the number of participating players or to modify the rules by which a game is won. The students learn how their program planning (choice of data representation, for example) is likely to affect the degree of generality and the extension potential of a program. Furthermore, students are required to suggest and implement various extensions in their program according to different imposed changes.

4 Gradual Learning of Program Development, In Practice

This course went through several revisions. At the beginning, the course started with an emphasis of language features and their practice by writing single functions only. After few years of teaching the course we have realized that the gap between writing solitary functions (or even small modules) and writing a large-scale project was too large. The students found it difficult to perform tasks such as planning, decomposition, and integration by themselves. Intensive and close guidance on the teacher's part was needed; therefore the experience of independent team and personal work was partially lost.

To overcome that gap, a well-structured, carefully planned set of tasks was incorporated into the course from its early stages. This set focused on preparing the students for the final project. According to the current course plan, a major part of the course is devoted to a series of programming tasks whose complexity gradually rises. These tasks enable students to practice repeatedly the stages of software development and acquire an understanding of important principles, skills, and work habits.

For example, already after 12-15 study hours, a relatively complex task such as the following is introduced.

In a Tic-Tac-Toe game board there are 3 rows and 3 columns. Each square contains one of the following three signs: the first player's sign (X), the second player's sign (O) and the sign of an empty square. A "winning board" in the game is the board in which 3 consecutive squares (in a row, a column or a diagonal line) contain an X or 3 consecutive squares contain an O. Write a function that gets as a parameter a Tic-Tac-Toe game board and returns 'true' if it is a "winning board" and 'false' otherwise.

This task raises, at this relatively early stage, several issues in software design. One of the issues is comparing different ways for dividing the task into sub-tasks while emphasizing the writing of general functions. For example, checking the board for a "winning threesome" can be done with eight functions (for the three rows, three columns and two diagonals). Or, alternatively, with three generalized functions: for the rows, for the columns and for the diagonals, and so on.

Another issue is the comparison between different representations of the game board: a transformation of the matrix to a linear list of nine items, or a list with three sub-lists representing the three rows on the board, or a list of nine sub-lists each composed of row, column and a sign. In order to realize the representation effect on the ease of the operations' implementations, students are asked to implement, using those representations several functions, such as updating the value of a square in the board, or checking whether a square is empty, and weighing considerations regarding which representation is preferred.

After learning conditionals and recursion, gradually more advanced tasks are presented. Each task both practices various stages in software design and adds a new element related to development of a game. For example, simulation of a lottery drawing (with no repetition) applies working with random numbers. Simple games like Hangman and other guessing games put writing interactive programs into practice. The card game of "War" between two players shows mutual recursion and players' taking turns.

5 Summary

Since basic tools of the DrScheme environment can be acquired in a relatively short time, more attention is given to basic principles of computer science and of software design and development. A course such as the one described in this paper contributes to beginning students on several levels:

  • Early exposure and significant experience in the development process of complex programs.
  • Building a complete product, a program that can be played with, from scratch.
  • Experiencing and comprehending recursion.

Beyond the contributions in the context of programming, the developments of interesting and useful programs produce great enthusiasm among the students. Students' motivation and enjoyment are evident through the highly creative and original software they develop. Our experience shows that developing a project constitutes an attractive and challenging framework for strong students who choose to expand beyond the course requirements and integrate additional graphic functions into their programs. Moreover, teachers report of students being better prepared for the more advanced CS courses.

6 References

Abelson, H., Sussman, G.J. & Sussman, J. (1996). Structure and Interpretation of Computer Programs. Second Edition. MIT Press, Cambridge, Massachusetts, London, England.

Felleisen, M., Findler, R.B., Flatt, M. & Krishnamuethi, S. (2001). How to Design Programs. An Introduction to Computing and Programming. Cambridge, Massachusetts: The MIT Press. Available: http://www.htdp.org/2001-01-18/Book/

Gal-Ezer, J., Beeri, C., Harel, D. & Yehudai, A. (1995). A high school program in computer science. IEEE Computer. 28 (10), 73-80.

Leron, U. (1987). Abstraction barriers in mathematics and computer science. In J. Hillel (Ed.). Proceedings of the Third International Conference for Logo and Mathematics Education. Montreal: Concordia University.

Leron, U. (1988). What makes recursion hard?. Proceeding of the Sixth International Congress of Mathematics Education (ICME6). Budapest (Hungary).

Leron, U., Lapidot, T., Levy, D. & Paz, T. (1999). Functional Programming, Additional Programming Paradigm. Workbook 1-2 for Students and a Teachers' Guide. Technion—Israel Institute of Technology. (in Hebrew).

Mann, L.M., Linn, M.C. & Clancy, M.J. (1994). Can tracing tools contribute to programming proficiency? the LISP evaluation modeler. Interactive Learning Environments. Vol. 4, No. 1, pp. 96-113.

Paz, T. (2003). Natural Thinking vs. Formal Thinking: The Case of Functional Programming. Unpublished PhD thesis, Technion—Israel Institute of Technology (in Hebrew).

Pressman, R.S. (2001). Software Engineering: a practitioner's approach. 5th Edition. Boston: McGraw-Hill.

Segal, J. (1995). Empirical studies of functional programming learners evaluating recursive functions. Instructional Science. Vol. 22, pp. 385-411.

Wirth, N. (1971). Program development by stepwise refinement. Communications of the ACM. Vol. 14, No. 4, pp. 221-227. Available: http://www.acm.org/classics/dec95/

Contact:

Tamar Paz
Department of Education in Technology and Science
Technion, Israel Institute of Technology, Haifa 32000 Israel
tamarp@tx.technion.ac.il

Orna Muller
Computer Science Group, Science Education Department
School of Education
Tel-Aviv University, Israel
ornamu@post.tau.ac.il

 

1 The DrScheme environment can be downloaded at the following Web site: http://download.plt-scheme.org/drscheme/

2 An atom is a number, a string, a symbol, or a Boolean value.
A list is an ordered set of elements consisting of atoms or other lists.

3 The DrScheme environment allows direct assignment, as in the following expression (set! colors '(red blue white yellow))

Customer Service: iste@iste.org   1.800.336.5191   1.541.302.3777 (Int'l)   1.541.302.3778 (fax)
Visit the ISTE Career Center for educational technology jobs, resources, and listings. Copyright 1997-