Know how to interpret and write expressions in prefix operator notation
Know how to interact with the Racket interpeter in DrRacket
Know how to represent and work with basic data types (booleans, numbers, strings) in racket.
Know how to define and use functions in Racket using
lambda
Know how lexical scope works in Racket, and how to introduce
local variables using let
and let*
.
About me
About the course
Some getting-started logistics:
Take two minutes to think about group work experiences you’ve had in the past (in this class or otherwise). Consider:
Take five minutes with your team to:
Write your norms on the Team Norms sheet.
I’ll collect these after class and redistribute them with the Exercise/Problem sheets each day.
We’ll occasionally revisit norms and make any adjustments deemed necessary.
Do “Exercises” Part N
Functions (methods, operators, procedures, etc. etc.) are core to programming - even more so than you may have recognized!
Consider applying a function/operator (say, addition) to two arguments \(a\) and \(b\).
Math: \(a + b\)
Most programming languages: add(a, b)
Lisp and its relatives: (+ a b)
, or
(add a b)
This is called prefix notation - where the operator (or function) appears before its arguments.
Let’s play in DrRacket:
+ 2 3)
(* 1 6)
(/ 2 0) ; hope this throws an error! btw, comments start with ;
(max 9 7) ; racket has a bunch of builtin functions
(max 9 7 12) ; there might be occasional benefits to this prefix notation thing...
(
integer? 12) ; booleans look like #t and #f
(number? 12) ; predicates (functions that return a boolean) traditionally end in ?
(string? 12)
(string? "abc")
(boolean? #f) (
define base 4) ; syntax: (define <symbol> <value>)
(define height 2)
(
base
; area of a triangle with base 4 and height 2 = 1/2 * base * height
/ (* base height) 2) (
lambda
Functions (or procedures) are created with the lambda
special form:
lambda (x) (+ x 2)) ; evaluates to a function (or procedure)
(lambda (x) (+ x 2)) 4) ; applies the function to the argument 4
((
define addxy (lambda (x y) (+ x y))) ; store a function in a global variable
(4 8) ; apply the function to 2 arguments (addxy
Do exercises Part A
Scope in Racket is lexical - variables are visible
only within a certain segment of the program text. define
creates global variables whose scope is the entire program.
Function parameters (x
and y
, in the
addxy
example above) are local variables.
They’re only visible inside the procedure body, and they
shadow any global variable with the same name.
define x 1)
(4 5) ; should be 9, because the x inside addxy gets bound to 4, shadowing global x (addxy
If you want to create local variables that are not function
parameters, you can do that with let
:
let ((var1 val1)
(
(var2 val2)
(var3 val3))
(expression-using-variables))
; var1 and friends are not visible here
define a 4)
(
let ((a 1) ; shadows the global a
(2))
(b + a b)) (
The local variables initializations happen (conceptually, though not actually) in parallel. This means a later one can’t reference an earlier one:
let ((a 1)
(+ a 1))) ; error: a is undefined!
(b (+ a b)) (
We could nest let
s to make this work:
let ((a 1))
(let ((b (+ a 1)))
(+ a b))) ; this works (
There’s a shorthand syntax for this - let*
:
let* ((a 1)
(+ a 1)))
(b (+ a b)) (
Do Exercises Part B