Here's a simple macro that prevents same-argument recursive calls (including 
non-tail ones).  It's illustrated by a student function that made a teeny 
mistake which would result in looping forever, but (using this macro) instead 
signals an error.  To the best of my limited knowledge, beginner is purely 
functional aside from the use of the test functions, right? So any recursive 
call with eq? args is guaranteed to loop forever, right?

Hmm... well, I suppose there's (random)... 

It seems to me that a macro like this one (or even complete memoization) could 
potentially reduce student frustration, and would not prevent students from 
writing the programs that they wanted to.

No?

John Clements



#lang racket

(require rackunit)

(define-syntax (define/noloop stx)
  (syntax-case stx ()
    [(_ (funname arg ...) body ...)
     #`(define funname
         (let ()
           (define fresh-key (gensym 'funname))
           (define (funname arg ...)
             (let* ([most-recent-args (continuation-mark-set-first #f 
fresh-key)]
                    [these-args (list arg ...)])
               (when (and most-recent-args
                          (= (length these-args)
                             (length most-recent-args))
                          (andmap eq? these-args most-recent-args))
                 (error 'funname "recursive call with identical arguments ~s is 
guaranteed to run forever." these-args))
               (with-continuation-mark fresh-key these-args
                 body
                 ...)))
           funname))]))

;; NOW I'M A STUDENT:

;; only-long-strings : (listof string) -> (listof string)
;; return a list containing the strings longer than 2 chars
(define/noloop (only-long-strings l)
  (cond [(empty? l) empty]
        [else (cond [(< 2 (string-length (first l))) 
                     (cons (first l) 
                           (only-long-strings (rest l)))]
                    [else (only-long-strings l)])]))


(check-equal? (only-long-strings (cons "abc" (cons "de" (cons "fgh" empty))))
              (cons "abc" (cons "fgh" empty)))

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_________________________________________________
  For list-related administrative tasks:
  http://lists.racket-lang.org/listinfo/dev

Reply via email to