---
title: Eboard 32  Deep recursion
number: 32
section: eboards
held: 2019-04-22
link: true
---
CSC 151 2019S, Class (expt 2 5):  Deep recursion
================================================

_Overview_

* Preliminaries
    * Notes and news
    * Upcoming work
    * Extra credit
    * Questions
* Quick preview
* Lab

Preliminaries
-------------

### News / Etc.

* Mentor sessions Thursday 7-8 p.m., Thursday 8-9 p.m., Sunday 5-6 p.m.
    * Note change in schedule.
* Folks should think about taking CSC 161 in the fall.  It's a great class,
  and you get to work with robots! 
* Sorry that I remain a bit behind on way too much.  I'm working on it.

### Upcoming work

* [Project proposal](../project) due tonight!
    * [Rubric](../project/rubric.txt) available for your perusal.
* Friday's quiz: Higher-order procedures, algorithm analysis, trees
* Reading for Wednesday: 
  [Algorithms for searching lists and vectors](../readings/searching)
    * And yes, it's ready.
* Flash cards Wednesday: Higher-order procedures, algorithm analysis, trees

### Extra Credit

_I would certainly appreciate suggestions of other extra credit activities
(preferably via email)._

#### Extra credit (Academic/Artistic)

* **New**: CS Table, Tomorrow, "The Cathedral and the Bazaar"
* **New**: "Plan your CS major with WGMC", tomorrow at 7pm.  All genders
  welcome.
* Dartanyan Brown discussion, 4pm Wednesday April 24, HSSC S3325
* Dartanyan Brown concert, 7:30 pm Wednesday April 24, Sebring-Lewis
* PBK Convo, Thursday, 11am: "Antievolutionism in Historical Perspective"
* **New**: McKibben lecture, Thursday, 4:15 p.m., JRC 101

#### Extra credit (Peer)

* **New**: Track and Field at Grand View on Friday.

#### Extra credit (Wellness)

#### Extra credit (Wellness, Regular)

* **Today** 30 Minutes of Mindfulness at SHACS (SHAW) every Monday 4:15-4:45
* Any organized exercise.  (See previous eboards for a list.)
* 60 minutes of some solitary self-care activities that are unrelated to
  academics or work.  Your email reflection must explain how the activity
  contributed to your wellness.
* 60 minutes of some shared self-care activity with friends. Your email
  reflection must explain how the activity contributed to your wellness.

#### Extra credit (Misc)

* **Tonight** Public speaking workshop - April 22 at 7pm in HSSC S3325, 
  with Kathy Clemons-Beasley '05.  

### Other good things 

### Questions

Someone posted Sam's dining hall price rant.  What's that about?

> I used to write an essay ('blog post) every day.

> I'm a Grinnell parent and a curmudgeon.

> I did the math.  Dining plans were more expensive than buying individual
  meals.

> <https://www.cs.grinnell.edu/~rebelsky/musings/>

> But it appears they were discussing a different rant, one about the
  "cash value" of a dining hall meal.  There are too many for me too
  keep track of.

How do I extract text from a directory?

> The files have a pattern.  Sam can also work on writing some helper
  code.

> The `(directory-list dir)` procedure produces a list of "paths".
  (Something like filenames, but not as strings.)

> The `(path->string path)` procedure converts a path to a string.

> We can filter out the ones of interest.

> We can use `file->string` with `map` to extract the contents of each.

> We can join them together with `apply` and `string-append`.

```drracket

;;; Procedure:
;;;   sandb-files
;;; Parameters:
;;;   pattern, a regular expression
;;; Purpose:
;;;   Make a list of all the SandB files that match the particular expression.
;;; Produces:
;;;   fnames, a list of strings.
(define sandb-files
  (lambda (pattern)
    (map (section string-append sandb <>)
         (filter (section regexp-match? pattern <>)
                 (map path->string
                      (directory-list sandb))))))

;;; Procedure:
;;;   sandb-text
;;; Parameters:
;;;   pattern, a regular expression
;;; Purpose:
;;;   Extract the text from all of the files that match the pattern.
;;; Produces:
;;;   text, a string
(define sandb-text
  (lambda (pattern)
    (apply string-append (map file->string (sandb-files pattern)))))
```

Quick preview
-------------

* When I'm doing something with lists, what if I also want to look at
  the sublists?
* E.g., tallying strings.

```drracket
(define tally-strings
  (lambda (lst)
    (if (null? lst)
        0
        (if (string? (car lst))
            (+ 1 (tally-strings (cdr lst)))
            (tally-strings (cdr lst))))))
```

```drracket
> (tally-strings '("a" 2 3 "b" ("d" "e")))
2
```

Question: Can we make it count the "d" and the "e"?

```drracket
(define deep-tally-strings
  (lambda (lst)
    (if (null? lst)
        0
        (if (string? (car lst))
            (+ 1 (deep-tally-strings (cdr lst)))
            (if (list? (car lst))
                (+ (deep-tally-strings (car lst))
                   (deep-tally-strings (cdr lst)))
                (deep-tally-strings (cdr lst)))))))
```

Key idea: If the first element of the list is also a list, recurse on
both the car and the cdr.

Problems with code above:

* Nested ifs.  Consider using cond.
* Three calls to `(deep-tally-strings (cdr lst))`.  Makes code harder
  to read. (Fortunately, only one will be executed.)

```drracket
(define deep-tally-strings
  (lambda (lst)
    (if (null? lst)
        0
        (let ([tally-of-rest (deep-tally-strings (cdr lst))])
          (cond
            [(string? (car lst))
             (+ 1 tally-of-rest)]
            [(list? (car lst))
             (+ (deep-tally-strings (car lst)) tally-of-rest)]
            [else
             tally-of-rest])))))

(define deep-tally-strings
  (lambda (lst)
    (if (null? lst)
        0
        (+ (cond
             [(string? (car lst))
              1]
             [(list? (car lst))
              (deep-tally-strings (car lst))]
             [else
              0])
           (deep-tally-strings (cdr lst))))))
```

Note: Deep recursion does not generally work well with tail recursion
(so-far and remaining).  Use direct recursion.

Lab
---

For `deep-contains?`, assume that the value is not a list or pair.

For deep recursion, don't use a helper with so-far and remaining.  (It
makes things harder.)

For `deep-alphabetically-first`, you can assume that none of the lists
are empty.

For exercise 6, you may find it easier to allow deep-reverse to act on
non-lists.

Writeup exercise 5.
