Named Let

Recursion in general and named let in particular provide a natural way to implement many algorithms, whether iterative, recursive, or partly iterative and partly recursive; the programmer is not burdened with two distinct mechanisms. —– R. Kent Dybvig (fn:1)

This paragraph made me think of Ogden's Basic English and the English Through Pictures by I.A. Richards and Christine Gibson. Avoiding unnecessary burdens makes for better learning and working with ideas. Named let might have a place in a sequence with the aim of learning the most lucid and widely useful constructs for working with a computer language.

“Named let” didn't make sense to me when I first read in The Scheme Programming Language. (fn:1)

While wrestling with Guile Scheme to automate image conversion and worksheet generation the term came to mind and I started using the structure. Named let is a compact way to accumulate values. I think Phillip Fong used to have on-line pages for teaching Lisp. The pages provided training in creating helper or auxiliary functions to retain values for more efficient recursion. A quick search just now show that Scheme has replaced Lisp. (fn:1)

Having forgotten about filter I used a named let “recur” along a list and remove empty strings.

(define exmplist '("" "This" "list" "has" "empty" "" "strings"))

(define rmv-empty
  (lambda (lows) ;; list of words
    (let f ((ls lows)(keep '()))
      (cond
       ((null? ls) keep)
       ((= 0 (string-length (car ls))) (f (cdr ls) keep))
       (#t (f (cdr ls) (cons (car ls) keep)))))))
 (rmv-empty exmplist)
;; => ("strings" "empty" "has" "list" "This") 

(use-modules (rnrs lists))
(filter (lambda (s) (< 0 (string-length s))) exmplist)
;; => ("This" "list" "has" "empty" "strings")

Before reinventing the wheel (filter) with rmv-empty I started using named let to get unique words from lists of words.

(define wordlist->uniques
  (lambda (wl) ;; wordlist
    (let f ((low wl) (keep '())) ;; list of words
      (cond
       ((null? low) keep)
       ((member (car low) keep)(f (cdr low) keep))
       (#t (f (cdr low) (cons (car low) keep)))))))

And then nested lets (fn:3) , and a named let me re-discover another wheel, getting the “intersection” of two lists. “Intersection” comes from a vaguely remembered if ever understood reading of Paul Graham's On Lisp. This is probably an inefficient way to do it, later I might discover ready-made compact procedures to make the code more concise. But the feeling that you can make whatever you need to do your work, that feeling is important. And some day this code might provide ideas for use in a grade direct learning sequence with Guile.

(define wl-intersection
  (lambda (wl1 wl2) ;; two wordlists
    (let ((u1 (wordlist->uniques wl1))(u2 (wordlist->uniques wl2)))
      (let ((us (short1of2l u1 u2)) (ul (long1of2l u1 u2)))
	(let f ((short us)(long ul)(keep ul))
	  (cond
	   ((null? short) keep)
	   ((member (car short) ul)(f (cdr short) long keep))
	   (#t (f (cdr short) long (cons (car short) keep)))))))))

(define long1of2l
  (lambda (l1 l2)
    (if (> (length l1) (length l2))
	l1
	l2)))
(define short1of2l
  (lambda (l1 l2)
    (if (> (length l1) (length l2))
	l2
	l1)))

I introduced this blog on Diaspora* too. – Diaspora Post

#Guile #OgdensBasicEnglish #IaR #GDM #NamedLet #KentDybvig #TSPL4 #PhillipFong