This page is a reference for the University of Toronto “Computational Thinking” Teaching Language, used in the Fall 2017 offering of CSC 104.
The Interactions Area is where you can enter an expression and have DrRacket immediately compute its value.
When you press Return (which might be labelled “Enter” on your keyboard), DrRacket checks whether you have written a complete expression (essentially: are all the parentheses “balanced”). If not, DrRacket simply moves the cursor to a new line, so you can complete or edit the expression you are creating. If you have written a complete expression, then pressing Return makes DrRacket compute the result of the expression and show you its value.
If you are editing an expression and want to spread it over multiple lines while you work on it (something you will see us do for more complex expressions to show their structure), then you can hold down the Shift key while you press Return. Holding down the Shift key prevents DrRacket from computing the expression, even if the expression looks complete.
There are four(!) ways to write something in your code so that what you write will be ignored by DrRacket when running the document. Something written for a human reader of your code, not for DrRacket to interpret, is called a “comment”.
A semi-colon “;” makes DrRacket ignore everything from it up to the end of the line it’s on, and the text will be given a different color than code. You can put a semi-colon at the start of many lines at once, by selecting multiple lines and then choosing the menu item “Racket / Commment Out with Semicolons” (turning something into a comment is called “commenting it out”, and this kind of comment is called an “end-of-line comment”). If you have many lines with semi-colons at the start, you can remove them all by selecting the lines and then choosing the menu item “Racket / Uncomment”
A comment box creates an area where text is still colored like code but otherwise ignored by DrRacket. You can insert one with the menu item "Insert / Insert Comment Box", and then type inside it. You can also comment out a part of your document by selecting it and then choosing the menu item "Racket / Comment Out with a Box".
Another way to comment out a part of your document is to surround it with the delimiting pairs of characters “#|” and “|#”. Like with semi-colons, the color will change. This kind of comment is called a “block comment”.
Finally, to make DrRacket ignore a definition or expression, you can put the two characters “#;” in front of the expression. This can be a little hard to notice at first, since of the definition or expression doesn’t change.
To see the steps to compute an expression, you can use DrRacket’s traditional Stepper, by pressing the “Step” button. To see a listing of all the steps, closer to our course’s style, use one of the following step or steps forms.
(steps expression/definition ...)
A “literal” image (as opposed to one computed by an image function) can be entered into DrRacket, and used as-is as a value in code.
You can find functions for modifying images, as well as creating geometric shapes, in later sections. But if you find an image that you would like to include, you can copy it into DrRacket from another application, from a file on your computer, or from a web address.
To copy an image from another application (for example a web browser), select/highlight it in the other application, using that application’s copy mechanism (which should be a menu item and/or a keyboard shortcut):
Then paste it into DrRacket (using DrRacket’s copy mechanism, for example the DrRacket menu item “Edit / Paste”, or the associated keyboard shortcut):
Sometimes, the copy-paste approach does not work for a particular application. If you can save the image from the application to a file on your computer, then you can insert it into DrRacket using the menu item “Insert / Insert Image...” and choosing the file:
If the image is on the web, and you know its address (“URL”), you can use bitmap/url to download and refer to it. First copy the URL, for example from your browser address bar:
Then use the following function (be sure to use the double-quotes, to make it a “string”):
> (bitmap/url "https://racket-lang.org/logo.png")
tcp-connect: connection failed;
host not found
port number: 443
system error: Name or service not known; gai_err=-2
You can also save an image from DrRacket to a file, using the image context menu (right-click on the image):
> (beside )
> (above )
alignment : (or/c "top" "bottom" "center" "baseline") an-image : image? (above/align alignment an-image ...) → image? alignment : (or/c "left" "right" "center") an-image : image?
> (beside/align "baseline" (string->image "play" 30 "tomato") (string->image "a" 40 "blue") (string->image "jig" 20 "darkgreen"))
(overlay/align horizontal-alignment vertical-alignment an-image ...) → image? horizontal-alignment : (or/c "left" "right" "center") vertical-alignment : (or/c "top" "bottom" "center" "baseline") an-image : image?
> (define a-half-triangle (crop-right (triangle 40 "solid" "forestgreen") 20)) > a-half-triangle > (rotate-ccw a-half-triangle) > (rotate-180 a-half-triangle) > (rotate-cw a-half-triangle)
> (scale 2 )
an-image : image? (flip-vertical an-image) → image? an-image : image?
an-image : image? pixels : (and/c number? non-negative?) (crop-top an-image pixels) → image? an-image : image? pixels : (and/c number? non-negative?) (crop-right an-image pixels) → image? an-image : image? pixels : (and/c number? non-negative?) (crop-left an-image pixels) → image? an-image : image? pixels : (and/c number? non-negative?)
an-image : image? (image-height an-image) → natural? an-image : image?
> (image-width (rectangle 5 30 "solid" "purple"))
> (image-height (rectangle 5 30 "solid" "purple"))
> (image-width (circle 200 "solid" "orange"))
> (image-height (above (circle 200 "solid" "orange") (rectangle 5 30 "solid" "purple")))
radius : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color?
side-length : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color? (triangle side-length mode color) → image? side-length : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color?
width : (and/c number? non-negative?) height : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color? (ellipse width height mode color) → image? width : (and/c number? non-negative?) height : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color?
distance : (and/c number? non-negative?) mode : (or/c "solid" "outline") color : image-color?
> (star 20 "solid" "yellow")
> (image-color? (list 12 56 34))
> (image-color? (list 0 100 0 100))
> (image-color? "orange")
> (image-color? "ORANGE")
> (image-color? "Black")
> (image-color? "bloo")
> (image-color? "transparent")
A list of three or four percentages represents a color with that percentage of red, green, blue, respectively, and optionally how opaque the color is (which defaults to 100 if unspecified).
string : string? font-size : (and/c natural? (<=/c 1 255)) color : image-color?
> (- 7)
> (- 7 2)
> (/ 12 2)
> (sqr 5)
Whole-number division, also called “integer division”, is a version of division (/) If you are not familiar with the terms “integer” and “natural number”, see Types of Numbers. that produces a whole number “quotient” along with any leftover “remainder”.
The predicate number? in Types of Data asks whether a value is a number. If you have not learned the term “predicate” yet: it means a function that produces a boolean. If you have not learned the term “boolean” yet: it means one of the special values #true or #false. Predicates in this section determine whether a value is a particular kind of number.
(natural? v): is v a natural number (one of the numbers 0, 1, 2, 3, ...)?
(zero? x): is the number x equal to zero?
(non-negative? x): is the number x at least zero?
(positive? x): is the number x greater than zero?
> (negative? -2)
> (negative? 0)
> (negative? 2)
> (zero? -2)
> (zero? 0)
> (zero? 2)
> (non-negative? -2)
> (non-negative? 0)
> (non-negative? 2)
> (positive? -2)
> (positive? 0)
> (positive? 2)
Notice these predicates expect a number (and report an error otherwise).
(even? i): is integer i even (a multiple of 2)?
(odd? i): is integer i odd (not a multiuple of 2)?
x : number? (string->number s) → (or/c number? #false) s : string?
(define name expression)
The variable cannot have the same name as another variable or a function, and the variable cannot be used inside expression.
(define (name parameter-name parameter-name ...) expression)
When the function is called, the values of the arguments are inserted into the body in place of the parameter-names, and the function produces the value of that new expression.
The function cannot have the same name as another function or a variable.
(local [definition ...] expression)
Each definition must be a define form.
Each definition occurs, and then the result of the body expression is computed and used as the result of the whole local expression.
The definitions last only while the local result is being produced, and the names they define can only be referred to within the local. The definitions can define a name that already has a definition outside the local, in which case the local definition takes precedence inside the local.
A string is used to represent text. It is a sequence of characters, entered by surrounding the characters with double-quotes. The double-quotes are not considered part of the text itself, or put another way: they are not characters in the string itself. The double-quotes are just there to know where the text starts and ends, so the characters they surround are not interpreted as code.
There are various special “characters” in computing, for example the character to represent the end of a line in text that spans multiple lines. And putting a double-quote itself inside a string as one of its characters requires some way to indicate that the double-quote is not just signalling the end of the string. We avoid these technicalities, except if they become necessary or useful for a particular text processing task. If they come up naturally we will address them in that context, so except where we explicitly state otherwise, you can safely assume none of our strings will contain double-quotes as characters, nor span multiple lines.
> (string-length "hello world")
> (string-append "hello" " " "world" ", " "good bye")
"hello world, good bye"
> (string-append "hello")
> (string-ref "hello world" 1)
> (string-contains? "it" "kitten")
s : string? (number->string x) → string? x : number?
> (string-alphabetic? "Cat")
> (string-alphabetic? "Cat?")
> (string-alphabetic? "123")
> (string-upper-case? "CAT")
> (string-upper-case? "kITTY")
> (string-upper-case? "CAT?")
> (string-lower-case? "cat")
> (string-upper-case? "kITTY")
> (string-lower-case? "cat?")
These functions compare two or more strings alphabetically.
The versions string<?, string>?, string<=?, and string>=? ignore the distinction between upper and lower-case (the “ci” in the name stands for “Case Insensitive”). See also string-ci=? in Equality, and also string-upper-case? and string-lower-case? in Types of Characters.
> (string-ci<? "al" "Beth" "dee")
> (string-ci>? "Zebra" "koala" "kitten")
> (string-ci<=? "al" "beth" "Beth" "dee")
> (string-ci>=? "zebra" "zebra" "Koala" "kitten")
s : character? (unicode->character n) → character? n : natural?
> (character->unicode "A")
> (unicode->character 65)
> (character->unicode "⚘")
> (unicode->character 9880)
The function that compares whether two values are the same is equal?, which works with any type of value.
There are also restricted versions of equal?, that work only on values of a particular type, and report an error otherwise. In situations where you expect values to be of a particular type, then using the restricted versions of equal? can be clearer to someone reading your code. Using these versions can also report some errors earlier (ones where your code produced values of the wrong type, and then compares them) and more closely related to the true source, making them more useful.
> (boolean=? #true #false)
> (string-ci=? "hello" "HellO")
(check-expect expression expected-expression)
The Boolean type has two values: #true and #false.
These forms are special because they selectively (“conditionally”) compute the result value of some of their component expressions.
(and expression expression expression ...)
An expression produces #false, in which case #false is used immediately (“short-circuiting”) as the result of the whole and expression.
An expression produces a non-boolean value, in which case an error is reported.
(or expression expression expression ...)
An expression produces #true, in which case #true is used immediately (“short-circuiting”) as the result of the whole or expression.
An expression produces a non-boolean value, in which case an error is reported.
The paired question-and-answer [“condition” and “result”] expressions are known as “clauses”. People traditionally group a question-answer pair with square brackets, although parentheses can also be used, to emphasize that the clauses are not in the form of a function call, and to make it easier to see the two contained expression, which frequently are parenthesized forms themselves.
A cond computes each question-expression until: it finds the first one that produces #true, or all of them produce #false and it reaches the else. It then computes the result of the answer-expression for that clause, and uses that as the result of the whole cond expression.
If during this process one of the question-expressions produces a non-boolean value, then an error is reported.
Select the DrRacket menu item “Language / Choose Language ...”.
In the language chooser make sure that “CSC 104” is selected, and then click the “Show Details” button.
Select the option “Prefix result values with their types”, then click the “Ok” button.
The language shown in the lower left corner of DrRacket should now say “CSC 104 custom”, and be highlighted (confirming that a language option was changed).
Click the “Run” button so that the change takes effect. The highlighting of “CSC 104 custom” should now go away, and the Interactions area should now say the language is “CSC 104 [custom]”.
Enter a value into the Interactions area to see the new behaviour.
> (image? )
> (number->string 104)
string : string? font-size : (and/c natural? (between/c 1 255)) color : image-color?
> (string->image "Hi!" 30 "olive")
> (string->list "a kitten")
(list "a" " " "k" "i" "t" "t" "e" "n")
A list bundles (“contains”, “holds”) zero or more values (known as its “members”, “elements”, or “items”), into a single “compound” value. One way to create a list is with list, which is also how lists are shown in the Interactions.
The list with no elements is known as the “empty” list. There are two traditional alternatives for referring to the empty list. If you use only materials referred to in this instance of the course, then the alternatives should not appear, and you can safely ignore the rest of this paragraph. But if you look outside this instance of the course (for example, to some previous versions of the course), you might encounter the synonyms empty or '().
> (range 2 10 3)
(list 2 5 8)
> (map string-length (list "rick" "and" "morty"))
(list 4 3 5)
> (list (string-length "rick") (string-length "and") (string-length "morty"))
(list 4 3 5)
> (make-list 3 "hello")
(list "hello" "hello" "hello")
> (remove-all "hello" (list 2 "hello" #true "hello"))
(list 2 #true)
> (remove-all "bye" (list 2 "hello" #true "hello"))
(list 2 "hello" #true "hello")
(big-bang start [on-tick updater] [to-draw drawer])
A big-bang expression also produes a result value, after you close its animation window: the updated version of start that was used to produce the last image shown.
(big-bang start [on-tick updater])
(repeated updater start n)
(big-bang start [to-draw drawer])
(identity v) → any/c
v : any/c
If we use a library in the course, then we will describe how to install it (if necessary), and give you the exact expression to write in order to use the library.