Assignment Chef icon Assignment Chef
All English tutorials

Programming lesson

Mastering Recursion in Racket: A Step-by-Step Lab Guide for CSCI 301

Learn recursion in Racket through a detailed walkthrough of CSCI 301 Lab 2. Understand the mystery function, debugging, and write recursive functions like gen-list, sum, retrieve-first-n, and pair-sum?.

Racket recursion tutorial CSCI 301 lab 2 recursive functions Racket mystery function explained DrRacket debugger gen-list Racket sum list Racket retrieve-first-n Racket pair-sum? Racket begin displayln Racket functional programming recursion scheme recursion examples programming lab help racket assignment help recursion debugging tips

Introduction: Why Recursion Matters in Racket

Recursion is the backbone of functional programming, and Racket (a dialect of Scheme) makes it elegant. In this tutorial, we'll break down the key exercises from CSCI 301 Lab 2, helping you master recursion without copying solutions. Whether you're coding a recursive function to generate a list or debug a mysterious function, these skills are essential for your programming toolkit. Let's dive in with a timely analogy: think of recursion like a viral TikTok challenge—each step builds on the previous one until you reach a base case (the final video).

1. Understanding the Mystery Function

What Does (mystery '(1 2 3)) Return?

Load the function:

(define (mystery L) (if (null? L) L (append (mystery (cdr L)) (list (car L)))))

Run (mystery '(1 2 3)). The result is (3 2 1). The function reverses the list! How? It recursively processes the tail (cdr L), then appends the head (car L) as a single-element list at the end. For (mystery '((1 2) (3 4) 5 6)), you get (6 5 (3 4) (1 2)). The function reverses the top-level list, preserving sublists as elements.

How Does the Return Value Work Without a Return Statement?

In Racket, every expression evaluates to a value. The if expression returns either the consequent (when condition is true) or the alternative (when false). The function's body is a single expression, so its value becomes the function's return. No explicit return needed—the last evaluated expression is the result.

2. Debugging with DrRacket: Step Through Recursion

Click the Debug button and run (mystery '(1 2 3)). Use Step to watch the green arrow move through code. The gray bar shows return values. Hover over L to see its current value. The stack trace on the right shows nested calls. This is like watching a recursive function unfold in slow motion—perfect for understanding how each call builds toward the final result.

3. Adding Output: The Role of begin and displayln

Modify the function:

(define (mystery L) (if (null? L) L (begin (displayln L) (append (mystery (cdr L)) (list (car L))))))

begin sequences multiple expressions; it evaluates them in order and returns the last one's value. displayln prints its argument followed by a newline, but returns #<void>. So begin allows you to print before computing the recursive call. Run it and see each recursive call's L printed.

4. Write gen-list: Generate a List of Consecutive Integers

Define a recursive function that builds a list from start to end. Base case: if start > end, return empty list. Otherwise, cons start onto the result of (gen-list (+ start 1) end).

(define (gen-list start end) (if (> start end) '() (cons start (gen-list (+ start 1) end))))

Test: (gen-list 1 5)(1 2 3 4 5).

5. Write sum: Add Up All Elements in a List

Recursively add the first element to the sum of the rest. Base case: empty list returns 0.

(define (sum lst) (if (null? lst) 0 (+ (car lst) (sum (cdr lst)))))

Test: (sum '(4 5 0 1)) → 10; (sum (gen-list 1 5)) → 15.

6. Write retrieve-first-n: Return First n Elements

Return the first n elements of a list. Handle edge cases: if n <= 0, return empty; if n >= length, return the whole list.

(define (retrieve-first-n n lst) (cond ((<= n 0) '()) ((null? lst) '()) (else (cons (car lst) (retrieve-first-n (- n 1) (cdr lst))))))

Test: (retrieve-first-n 3 '(a b c d e f g h i))(a b c).

7. Write pair-sum?: Check Adjacent Pairs Sum to a Value

Check if any two adjacent elements sum to val. Base cases: if list has fewer than 2 elements, return #f. Otherwise, check if (+ (car lst) (cadr lst)) equals val; if yes, return #t; else recurse on (cdr lst).

(define (pair-sum? lst val) (cond ((< (length lst) 2) #f) ((= (+ (car lst) (cadr lst)) val) #t) (else (pair-sum? (cdr lst) val))))

Test: (pair-sum? '(1 2 3) 3)#t; (pair-sum? (gen-list 1 100) 1000)#f.

Conclusion: Recursion as a Superpower

Recursion in Racket is like a chain reaction: each call reduces the problem until a base case stops it. By writing gen-list, sum, retrieve-first-n, and pair-sum?, you've practiced the core pattern. Remember to use the debugger to visualize recursion—it's your best friend. Now go ace that lab!