Download as pdf or txt
Download as pdf or txt
You are on page 1of 37

Lecture 3: Introduction to Racket

CMSC 15100 — Winter 2018


University of Chicago

January 8, 2018
Review

Recall from the last lecture that Typed Racket has a uniform syntactic
structure, where a term is either an identifier or constant, or it is an
operator with zero or more arguments (or subterms):

( operator arg1 arg2 · · · )


and that we have introduced three basic forms: definitions (with type
annotations) and expressions.

January 8, 2018 Lecture 3 2


Review (continued ...)

For example, say that we want


c
to compute the hypotenuse (c) a

of a triangle.
b

First, we can bind names to the Then, we can compute the


lengths of the sides hypotenuse as an expression

January 8, 2018 Lecture 3 3


Review (continued ...)

For example, say that we want


c
to compute the hypotenuse (c) a

of a triangle.
b

First, we can bind names to the Then, we can compute the


lengths of the sides hypotenuse as an expression
(: a : Integer)
(define a 3)
(: b : Integer)
(define b 4)

January 8, 2018 Lecture 3 3


Review (continued ...)

For example, say that we want


c
to compute the hypotenuse (c) a

of a triangle.
b

First, we can bind names to the Then, we can compute the


lengths of the sides hypotenuse as an expression
(: a : Integer) (sqrt (+ (* a a) (* b b)))
(define a 3) =) 5
(: b : Integer)
(define b 4)

January 8, 2018 Lecture 3 3


Abstracting over expressions

The previous example illustrates how we can compute the hypotenuse of a


single triangle.
But what if we want to compute the hypotenuse of a bunch of triangles?
To avoid writing the same expression out repeatedly, we can generalize it
by defining a function that abstracts over the variables a and b

January 8, 2018 Lecture 3 4


Abstracting over expressions

The previous example illustrates how we can compute the hypotenuse of a


single triangle.
But what if we want to compute the hypotenuse of a bunch of triangles?
To avoid writing the same expression out repeatedly, we can generalize it
by defining a function that abstracts over the variables a and b

January 8, 2018 Lecture 3 4


Abstracting over expressions

The previous example illustrates how we can compute the hypotenuse of a


single triangle.
But what if we want to compute the hypotenuse of a bunch of triangles?
To avoid writing the same expression out repeatedly, we can generalize it
by defining a function that abstracts over the variables a and b

(: hypot : Real Real -> Real)


;; compute the hypotenuse of a right triangle
(define (hypot a b)
(sqrt (+ (* a a) (* b b))))

January 8, 2018 Lecture 3 4


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Functions

The general form of a function definition is


(: f : ty 1 · · · ty n -> ty)
(define (f x1 · · · xn ) exp)

where
I f is the name of the function
I ty1 · · · tyn -> ty is the type (or signature) of the function
I the variables x1 , . . . , xn are the parameters of the function
I the expression exp is the body of the function.
I The parameter xi has type tyi in its scope exp.
I the function’s body exp has type ty.

January 8, 2018 Lecture 3 5


Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Design pattern for functions
HtDP espouses a particular approach to software development that places a
heavy emphasis on testing.
Once you have determined the need for a given function (e.g., from
problem decomposition), you use a design recipe to guide the
implementation of that function:

I Data — what types of values does the function consume and


produce?
I Examples — what are examples of the function’s use?
I Type signature — what is the type of the function?
Note that the book calls the type signature the contract.
I Purpose comment — what is the purpose of the function?
I Body — the code that implements the function.
I Tests — after implementing the function, revisit the examples. Do
they exercise all of the code that you have written
January 8, 2018 Lecture 3 6
Testing

The computer has no special knowledge of how hypot (for example) is


supposed to behave.
Fortunately, DrRacket provides some infrastructure for testing correctness.
The most important mechanism is check-expect, which tests if an
expression returns the expected value.
For example:

The invocation of test is usually placed at the end of the source file. It
causes the tests to be run.

January 8, 2018 Lecture 3 7


Testing

The computer has no special knowledge of how hypot (for example) is


supposed to behave.
Fortunately, DrRacket provides some infrastructure for testing correctness.
The most important mechanism is check-expect, which tests if an
expression returns the expected value.
For example:

The invocation of test is usually placed at the end of the source file. It
causes the tests to be run.

January 8, 2018 Lecture 3 7


Testing

The computer has no special knowledge of how hypot (for example) is


supposed to behave.
Fortunately, DrRacket provides some infrastructure for testing correctness.
The most important mechanism is check-expect, which tests if an
expression returns the expected value.
For example:

The invocation of test is usually placed at the end of the source file. It
causes the tests to be run.

January 8, 2018 Lecture 3 7


Testing

The computer has no special knowledge of how hypot (for example) is


supposed to behave.
Fortunately, DrRacket provides some infrastructure for testing correctness.
The most important mechanism is check-expect, which tests if an
expression returns the expected value.
For example:
(check-expect (hypot 3 4) 5)

(test)

The invocation of test is usually placed at the end of the source file. It
causes the tests to be run.

January 8, 2018 Lecture 3 7


Testing

The computer has no special knowledge of how hypot (for example) is


supposed to behave.
Fortunately, DrRacket provides some infrastructure for testing correctness.
The most important mechanism is check-expect, which tests if an
expression returns the expected value.
For example:
(check-expect (hypot 3 4) 5)

(test)

The invocation of test is usually placed at the end of the source file. It
causes the tests to be run.

January 8, 2018 Lecture 3 7


Testing (continued ...)

For inexact computations, we use check-within and check-range


;; check that |e1 e2 |  ✏
(check-within e1 e2 ✏)

;; check that lo  e  hi
(check-range e lo hi )

January 8, 2018 Lecture 3 8


DEMO

January 8, 2018 Lecture 3 9


Conditionals

So far, we have been using the computer as a glorified calculator. Things


become much more interesting when we allow programs to make choices.
In Typed Racket, we use the cond construct to specify conditional code.
Its basic form is

The semantics of cond is that each predicate expression predi is evaluated


in order until a predicate returns #t, at which point the corresponding
expression is evaluated.

January 8, 2018 Lecture 3 10


Conditionals

So far, we have been using the computer as a glorified calculator. Things


become much more interesting when we allow programs to make choices.
In Typed Racket, we use the cond construct to specify conditional code.
Its basic form is
(cond
[ pred 1 exp 1 ]
···
[ pred n exp n ]
[ else exp n+1 ])
The semantics of cond is that each predicate expression predi is evaluated
in order until a predicate returns #t, at which point the corresponding
expression is evaluated.

January 8, 2018 Lecture 3 10


Conditionals

So far, we have been using the computer as a glorified calculator. Things


become much more interesting when we allow programs to make choices.
In Typed Racket, we use the cond construct to specify conditional code.
Its basic form is
(cond
[ pred 1 exp 1 ]
···
[ pred n exp n ]
[ else exp n+1 ])
The semantics of cond is that each predicate expression predi is evaluated
in order until a predicate returns #t, at which point the corresponding
expression is evaluated.

January 8, 2018 Lecture 3 10


Conditionals (continued ...)

The semantics of the cond can be made more formal by symbolic


rewriting rules:

(cond [#f e] · · · ) ⇒ (cond · · · )


(cond [#t e] · · · ) ⇒ e
(cond [else e]) ⇒ e
(cond) ⇒ error!

Notice that cond is non-strict in its arguments!

January 8, 2018 Lecture 3 11


Conditionals (continued ...)

The semantics of the cond can be made more formal by symbolic


rewriting rules:

(cond [#f e] · · · ) ⇒ (cond · · · )


(cond [#t e] · · · ) ⇒ e
(cond [else e]) ⇒ e
(cond) ⇒ error!

Notice that cond is non-strict in its arguments!

January 8, 2018 Lecture 3 11


Conditionals (continued ...)

As an example, we can define an absolute-value function using cond:


(: absolute-value : Real -> Real)
;; return the absolute value of x
;;
(define (absolute-value x)
(cond
[(< x 0) (- x)]
[else x]))

(check-expect (absolute-value -1.5) 1.5)


(check-expect (absolute-value 0) 0)
(check-expect (absolute-value 1) 1)

January 8, 2018 Lecture 3 12


Other conditional forms

Racket has two additional logical operators:

(and #t · · · ) ⇒ (and · · · )
(and #f · · · ) ⇒ #f
(and) ⇒ #t

(or #f · · · ) ⇒ (or · · · )
(or #t · · · ) ⇒ #t
(or) ⇒ #f

January 8, 2018 Lecture 3 13


Summary

I Functions as a way to abstract over computations


I Design pattern for functions
I Layout of function code: signature, purpose, definition, tests
I Using check-expect
I Conditional expressions

January 8, 2018 Lecture 3 14

You might also like