Frequently Asked Questions
about Racket and Scheme
Why do you talk about Racket and Scheme?
Racket is a fork of Scheme, the simple language at the core of
this course for many years. Scheme was created primarily as an
experiment in understanding how programming languages work. Racket
retains its basic favor, but it also adds many, many features that
make the language useful in the 21st century. (It also changes a
few details that make it more useful to modern programmers.)
We use Racket in this course because it is more modern, has
better tools, and a thriving community doing cool work. But
there are so many valuable references from the Scheme world that
it's hard to talk about Racket in this course without referring
Questions about Specific Details of Racket
- Where did the names of the procedures cons,
car, and cdr come from?
- These names are an homage to the first implementation of Lisp,
on an IBM 704. A word on the 704 consisted of two parts, the
address register and the decrement register.
car and cdr were macros for accessing the
contents of the address
register and the contents of the
decrement register, respectively.
Scheme modernized many things about Lisp, but kept these
names for reasons both of culture and convenience. You can
read more about them, including the convenience reasons and
even the IBM 704 macro code for the car and
cdr macros, at the Wikipedia pages for
car and cdr.
Racket modernizes Scheme in many ways, including by adopting
Common Lisp's names for these fundamental procedures:
first and rest.
cons is the sort of abbreviation that most programmers
love. It is the procedure for constructing lists.
More specifically, cons allocates a single two-address
cell, which we usually just call a cons cell.
In this sense, cons is an inverse of car and
- Are Racket identifiers case-sensitive?
- Yes. Even so, we rarely use embedded capitals when naming
things in Racket. Instead, we use punctuation characters,
especially the hyphen. Instead of LastElement, we
would say last-element.
- Does Racket provide operators for programming with side
- Yes. However, side effects are not part of the functional
style of programming, so we do not reach them until much
later in the course. We have seen and used one operator
with side effects at the top level: define, which
binds a name to a value. Because define expressions
are evaluated for their side effects, Dr. Racket does not
print or return a value for them. Later, we will see
set!, which gives us the ability to change the value
of an existing binding, and begin, which gives us
the ability to sequence expressions. Finally, input/output
procedures such as read, write, and
print have side effects, too.
- The list is Racket's basic aggregate data type. Can we
make multidimensional lists?
- Yes. A list can be a list of any values, including other
lists! We will take advantage of this flexibility often,
with lists containing other lists of arbitrary length.
- Is there a list of all of Racket's primitive procedures?
- I do not know of a simple list of all the procedures defined
in Racket's base language. However,
the index to the Racket language reference
includes all the procedure and symbol names in the language.
Racket is a large language, so this list is quite long.
For this course, we can often use
of Revised Report on the Algorithmic Language Scheme,
as a quick reference. All, or nearly all, of those functions
exist in racket, too.
- How can I tell if a procedure is primitive or not?
- This can be tough when reading lecture notes, because sometimes
I use a function we defined in class previously. Other times,
we write our own functions to define the behavior of a built-in
To determine if a procedure is a Racket primitive, you can
search for it in
The Racket Guide,
using the search box at the top of every page.
You have another way to determine if a procedure is built into
Racket: evaluate the name of the procedure in Dr. Racket! If
you have not defined a procedure with that name, and
the name evaluates to a compiled #<procedure:...>,
then the procedure must be a Racket primitive.
If it causes an error because the name is not bound to a
value, then it's not.
... foo: undefined;
cannot reference an identifier before its definition
Questions about Racket as a Programming Language
- Are Racket procedures defined in libraries, as in Java?
- Not the primitives; they come as a standard part of the
language interpreter, just like Java primitives do. Of
course, people do create their own libraries of procedures
and load them into the Racket environment. In fact, you will
find that this is exactly what we do when we write Racket
Programming language researchers have long been working on
module systems that allow programmers to share
libraries of procedures more easily. Dr. Racket provides a
well-developed, full-featured module system.
- How has Scheme avoided bloat and creeping feature-itis?
- The language was originally designed as a minimalist language:
What is the smallest set of features we need to talk about all
the programming languages ideas that matter? As it moved from
the lab out into the world, new operators were added to Scheme,
making it more convenient to use. But it is still a minimalist
language, and the community of users that guides its evolution
is supportive of this mindset. As a result, features get added
to Scheme only when there isn't already a reasonable way to
implement the idea consistently using language features that
Racket extends Scheme in radical ways, but modularizes
extensions in separate languages. We will talk a bit about
this later in the semester.
- What are some of the restrictions that result from Scheme
being so small?
- It does not have 1001 primitives to make your life easier
from the outset. The language does not include primitives
for loops (at least commonly recogniziable ones), threads,
graphics, or even classes and objects.
Does that mean we cannot write programs using these ideas? No.
Scheme is more than powerful enough to implement all of these
ideas, plus ideas more complex than you are used to using. It
simply means that they we will have to find an implementation
of the idea, or roll our own. For example, I know of a couple
of canonical implementations of object-oriented programming
primitives for Scheme. If I want to do full OOP right now, I
would use one of them. Of course, as you'll see later in the
semester, we can implement OOP concepts on our own in relatively
Racket, on the other hand, is a full-featured language suitable
for building large software systems. It has most or all of the
features you might want.
- What are some of Scheme's weak points?
- If you want to build applications in the world, being small
is a weak point for a language. It's awfully nice to walk
up to Java and find a full blown GUI programming package
defined as part of the language.
So, people write their own and share. That creates a
portability problem. Unless a programmer implements a
library using only standard Scheme, there is a risk that
you won't be able to use the library on your system. It
may sound easy to use only standard Scheme, but in the
heat of implementing a big package it is awfully tempting
sometimes to use some of the non-standard features
available in your environment.
Scheme is different than most other languages programmers
use. It looks different, with all those parentheses and
lambdas. It feels different, with its emphasis on
functional programming and no side effects. Unfamiliarity can
be a weakness, because it makes the language less immediately
accessible to new programmers. It takes more effort to learn,
because it changes the programmer's habits.
The use of function composition and higher-order procedures
(we'll talk about that soon!) can result in "dense" code --
a small amount of code that implements a lot of different
ideas. Unlike Java and Ada, there isn't much dead space or
many dead characters. When a programmer is used to roomier
code, Scheme code can intimidate them.
The good news is that these weaknesses can be overcome
by time and effort. The unfamiliar can become familar. And
on the other side is a productivity and a sense of power that
is hard to imagine when slogging away in Java, C, or Ada.
- Does Racket have the same weak points?
- Racket addresses Scheme's weaknesses head-on. It offers
Scheme's level of productivity with features that make it an
able alternative to just about any other language you can
think of. Like any language, Racket is not perfect, but you
won't find any glaring holes in what it offers for building
- What is the lambda calculus?
- From an
on-line introduction to the lambda calculus
at Monash University:
The lambda calculus is a formal mathematical system devised by
Alonzo Church to investigate functions, function application, and
recursion. It has influenced many programming languages but none
more so than the functional programming languages. Lisp was the
first of these although only the "pure" Lisp sublanguage can be
called a true functional language. Haskell, Miranda, and ML are
more recent examples. Lambda calculus also provides the
meta-language for formal definitions in denotational semantics.
It has a good claim to be the prototype programming language.
The lambda calculus is in many ways the prototype for all
programming languages. Like the Turing machine, it is capable of
implementing any computable function. Unlike the Turing machine,
it focuses on the transformation rules that implement a function,
rather than the underlying machine implementation. Hence it lies
closer to the level of software than the Turing machine.
You can read a lot more about the lambda calculus at the
Monash University site.
You shouldn't be surprised later in the course when we use and
interpret a subset of Scheme that is remarkably similar to Church's
- What was the original purpose of Scheme?
- Steele and Sussman "discovered" Scheme in an effort to
design a minimal programminmg language. From Steele's
foreword to Scheme and the Art of Programming:
The original Scheme ... was a Swiss army knife. Hewing
close to the spirit of Alonzo Church's lambda calculus,
it had just one of anything if it had one at all.
Because Scheme is minimal whereas many of the languages
you know well are decidely not (C++, Ada, even Java), it
gives us a way to talk about the trade-offs between small
and large languages. Because Scheme is minimal, it leaves
us a lot of freedom to talk about most every language
feature, what they are useful for, how to implement them,
and what trade-offs they impose on us. Because Scheme is
minimal, it is small enough for us to master it well enough
to implement language interpreters in it.
Questions about Racket in the World
- Why use Racket to study programming languages?
- If Scheme has one niche to fill in the universe, it is as a
tool for studying languages. Scheme defines only a minimal
number of features, providing the atoms out of which we can
build and understand the molecules that are programming
language features. Racket extends Scheme but retains the
features that make it a perfect vehicle for studying
One of the reasons that Racket works so well for studying
languages is that symbols and lists are two of its primary
data types. In any language, once you move past the surface
syntax, a program can be thought of as a tree of symbols and
values. Trees are easily represented as lists of lists in
Racket, and symbols are first-order values.
Finally, as we will learn soon, programs are
recursively defined data structures, and using a
functional programming style exposes this in the interpreters
we write. Even more, functional programming takes advantage
of the recursive nature of programs to produce small, simple,
and relatively easy to understand interpreters.
- What can Racket do as a programming language?
- Anything that any other "general-purpose" language can do.
This is true in a theoretical sense, because Racket --
and even Scheme -- is "universal": any computable function
can be computed in it.
But Racket is universal in a practical sense, too.
People use Racket to write business data processing software,
network control software, AI programs, and even computer
The Racket team
eats its own dog food:
Racket and all of its tools, including Dr. Racket, are
written in Racket even the web server that supports
Of course, like any language, it is better suited for
some tasks than for others. Of course, the beauty of Racket
is that you can extend it to include any feature that you
want, or you can rather easily write an interpreter for a
more suitable task-specific language. That is The Racket Way.
- Is Scheme used for any "real world" programming?
- Yes, there are deployed, operational, "real" Scheme programs
working out in the world.
But. If your question is meant to imply that use
in "real" applications is necessary before you consider the
language worthy of the effort to learn, then my (only
partly) tongue-in-cheek answer becomes, "I don't care".
Not every language or skill you learn is directly applicable
to your job tomorrow. Our goal at the university is for
you to learn ideas that last for a while. No one
can predict with any certainty what language -- or even
kind of language -- you will be using in two, five,
or ten, years. But I can tell you what principles will
underlie their design, implementation, and use.
- Several virtual rides at Disney World are controlled
by programs written in
- Boeing and the U.S. Air Force use Racket programs to
control large, expensive telescope arrays.
Learning Racket will help you to learn those principles.
It will also help you to learn functional languages, and
languages with functional features, more easily later.
Practice learning a new language is worth the effort if only
because it makes learning the next one easier! (Of course,
if none of the tools and languages that you learn as
an undergraduate are used in the "real world", then you may
have cause to complain...)
Then again, if you believe
you should be using Racket or some other Lisp precisely
it is the most powerful language around.
- Why have I never heard of Racket or Scheme before? Will
- You have lived a short life. Appreciate the opportunity
to see the beauty of Racket before heading off into a world
filled with Curly Brace People.
Racket forked Scheme. Scheme forked Lisp. Lisp dates to 1958.
The first compiler was written in 1962. Scheme dates to the
fall of 1975. The code and tool base of Racket date to the
mid-1990s. Lisp evolves and survives.
Eugene Wallingford .....