2 The Principles of Racket

While we have reported on the pedagogic aspect of the project elsewhere (Felleisen et al. 2004), this paper presents the design principles behind Racket and illustrates with concrete examples how they affect the reality of its implementation. It groups these principles under three slogans:
  1. Racket is about creating new programming languages quickly.

    Programming is a form of problem solving. A proper approach uses the language of the domain to state the problem and to articulate solution processes. In support of this mode of programming, Racket helps programmers create and quickly deploy new languages. In particular, the mechanisms for creating and deploying languages must be contained within the language itself. Once Racket is installed, there must be no need to step outside to use one of its new languages. This principle is in stark contrast to the numerous external tools and command-line pre-processors that are used to create (embedded) domain-specific languages.

  2. Racket provides building blocks for strong protection mechanisms.

    If programming is about solving problems in the correct language, systems will necessarily consist of interconnected components in several different languages. Due to the connections, values flow from one linguistic context into another. Since languages are charged with providing and preserving invariants, the creators of languages must have the power to protect the languages’ invariants. By implication, Racket must come with mechanisms that enable programmers to protect individual components from their clients.

    For this reason, Racket comes with the proper building blocks to set up or construct protection mechanisms at any level, all the way from C to languages with sound, higher-order type systems, and any mixture in between.

  3. Racket turns extra-linguistic mechanisms into linguistic constructs.

    When programmers must resort to extra-linguistic mechanisms to solve a problem, the chosen language has failed them. Even if it is not always obvious how to fix such failures, programming language researchers ought to accept the general idea and try to work on finding the proper linguistic mechanisms. Due to Racket’s uses, the language currently internalizes several resource-management mechanisms that are often found in the underlying operating system. Similarly, this philosophy prohibits the idea of “projects,” as found in other IDEs, because this also externalizes resource management, linking, and other aspects of program creation.

Evaluating the use of such principles must take place in a feedback loop that encompasses more than the compiler for the language. In Racket’s case, the feedback loop’s evaluation stage contains a range of software systems, especially DrRacket (Findler et al. 2002), the Racket IDE.

The next three sections explain the principles in depth: language-oriented programming, protection mechanisms for full-spectrum programming, and services-as-constructs. The sixth introduces Racket’s design feedback loop in some detail and how it helps us use the guidelines to turn principles into reality. Finally the conclusions puts the principles in perspective, pointing out in particular where they remain goals and the research needed to reach those goals.