- practice, as distinguished from theory; application or use, as of knowledge or skills
- convention, habit, or custom
- a set of examples for practice
Computer programming, like any creative activity, demands constant study and practice. Vladimir Horowitz practiced the études of Chopin every night, after he performed a concert, to maintain his skills for the next performance. Tiger Woods drives a thousand balls on the driving range, every day. Pablo Picasso sketched a bull ten times before the eleventh bull was right. This blog publishes new programming exercises weekly, at least, so that savvy programmers can maintain their skills by working the exercises and thinking outside their normal skill set, whatever that is.
The programming exercises provided here aren’t a contest. No points are awarded, no scores are kept, there is no list of readers who have completed all the exercises. If you complete the exercise, and perhaps in doing so learn something that will help you be a better programmer, then your effort is its own reward. The exercises are intended to take about an hour to complete, on average, though of course the competence and creativity of the individual programmer, and the resources provided by the local computing environment, mean that the actual time spent on any given problem may range from minutes to hours. Although a sample solution is given for each programming exercise, there is no “right” answer, no perfect solution, in any sense. Thus, having completed an exercise, you may wish to do it again, using a different algorithm or a different programming language. Or you may wish to discuss your solution with other programmers in your office, or in your classroom, or in the comments of this blog.
Sample solutions are normally written in the Scheme programming language, which provides strong support for the exercises that make up the bulk of Programming Praxis. But there is no requirement that solutions be written in Scheme, and in fact any programming language may be used; in some cases, a different programming language may be better suited to a particular exercise. You can use these exercises to improve your skills at your primary programming language; an equally valid use of the exercises is to learn a new programming language. You may even find it useful to do the same exercise multiple times in different programming languages.
Scheme is a statically scoped and properly tail-recursive dialect of the Lisp programming language invented by Guy Lewis Steele Jr. and Gerald Jay Sussman. It was designed to have an exceptionally clear and simple semantics and few different ways to form expressions. A wide variety of programming paradigms, including imperative, functional, and message passing styles, find convenient expression in Scheme.
Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today.
Scheme was one of the first programming languages to incorporate first class procedures as in the lambda calculus, thereby proving the usefulness of static scope rules and block structure in a dynamically typed language. Scheme was the first major dialect of Lisp to distinguish procedures from lambda expressions and symbols, to use a single lexical environment for all variables, and to evaluate the operator position of a procedure call in the same way as an operand position. By relying entirely on procedure calls to express iteration, Scheme emphasized the fact that tail-recursive procedure calls are essentially goto’s that pass arguments. Scheme was the first widely used programming language to embrace first class escape procedures, from which all previously known sequential control structures can be synthesized. A subsequent version of Scheme introduced the concept of exact and inexact numbers, an extension of Common Lisp’s generic arithmetic. More recently, Scheme became the first programming language to support hygienic macros, which permit the syntax of a block-structured language to be extended in a consistent and reliable manner.
Scheme is defined by a series of Reports. The current standard is R6RS, but it is controversial, and an effort to replace it has already begun. Many implementations of Scheme still use the earlier R5RS standard [PDF] [HTML], and there are even some implementations of Scheme using the R4RS standard. A semi-official and widely-supported set of libraries is available as Scheme Requests for Implementation.
Students who are just learning to program and who are learning Scheme as their first programming language may be interested in the book How to Design Programs by Matthias Felleisen, Robert Bruce Findler, Matthew Flatt, and Shriram Krishnamurthi. For many years the first course in computer science at Massachusetts Institute of Technology was based on the book Structure and Interpretation of Computer Programs by Harold Abelson and Gerald Jay Sussman with Julie Sussman. Experienced programmers may want to look at Teach Yourself Scheme in Fixnum Days by Dorai Sitaram or The Scheme Programming Language by R. Kent Dybvig; the latter book has an excellent two-chapter tutorial on programming with Scheme.
There are many implementations of Scheme. DrScheme provides an excellent environment for students learning to program in Scheme, and has a wealth of libraries. Chez Scheme, which is the Scheme system used by Programming Praxis, provides a high-quality and very fast commercial compiler; the book Chez Scheme User’s Guide by R. Kent Dybvig describes Chez-specific extensions to Scheme, and a free version of the compiler is available as Petite Chez Scheme. Larceny was the first version of Scheme to support the new R6RS standard, and maintains compatibility with R5RS. And there are many other implementations of Scheme available; see schemers.org for a gateway to these implementations, and much other good on-line material about Scheme.
This blog is Copyright © 2009 by Programming Praxis of Saint Louis, Missouri, USA. All rights reserved. This work is licensed under the Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/3.0/us/ or send a letter to Creative Commons, 171 Second Street, Suite 300, San Francisco, California, 94105, USA. The “sharpen your saw” logo is due to Remco Niemeijer.
Suggestions for upcoming exercises are always welcome, and may be sent to the firstname.lastname@example.org.
An RSS feed for the entries on this blog is available at https://programmingpraxis.com/feed.