Search code examples
lambdaschemeracketletrec

Can a local procedure be bound to a variable in letrec without using lambda?


I am a beginner in scheme. I used to do programs like these in using letrec and binding using lambda.

(define (drop l n)
  (letrec ((iter (lambda(ls x)
  (cond ((null? ls) ls)
        ((> x 1) (cons (car ls) (iter (cdr ls) (- x 1))))
        (else (iter (cdr ls) n)))))) (iter l n)))

(define factorial
  (lambda (n)
    (letrec ((iter
              (lambda (product counter)
                (if (> counter n)
                    product
                    (iter (* counter product)
                          (+ counter 1))))))
      (iter 1 1)))

But i recently found that the valuation authorities in our college doesn't allow the use of the construct 'lambda'. Is there anyway that similar problems could be done without using lambda? Please suggest any other alternatives.


Solution

  • Let's examine a few variations (all in Racket).

    First your original:

    #lang racket
    (define factorial
      (lambda (n)
        (letrec ((iter
                  (lambda (product counter)
                    (if (> counter n)
                        product
                        (iter (* counter product)
                              (+ counter 1))))))
          (iter 1 1))))
    
    (factorial 5)
    

    The first lambda is easily hidden:

    (define (factorial2 n)
        (letrec ((iter
                  (lambda (product counter)
                    (if (> counter n)
                        product
                        (iter (* counter product)
                              (+ counter 1))))))
          (iter 1 1)))
    
    (factorial2 5)
    

    Internal defines and letrec are equivalent:

    (define (factorial3 n)
      (define (iter product counter)
        (if (> counter n)
            product
            (iter (* counter product)
                  (+ counter 1))))
      (iter 1 1))
    
    (factorial3 5)
    

    If you are using one of the teaching languages (for HtDP) the internal define is called a local definition - and you will have to use the local construct:

    (define (factorial4 n)
      (local [(define (iter product counter)
                (if (> counter n)
                    product
                    (iter (* counter product)
                          (+ counter 1))))]
        (iter 1 1)))
    
    (factorial4 5)