I've read here that named let
can be rewritten with letrec
.
And so I proceeded to rewrite the following function with letrec
:
(define (duplicate pos lst)
(let dup ([i 0] [lst lst])
(cond
[(= i pos) (cons (car lst) lst)]
[else (cons (car lst) (dup (+ i 1) (cdr lst)))])))
My attempt at this:
(define (duplicate pos lst)
(letrec ((dup (lambda ([i 0] [lst lst])
(cond
[(= i pos) (cons (car lst) lst)]
[else (cons (car lst) (dup (+ i 1) (cdr lst)))]))))))
Sadly, when I call it with (duplicate 1 (list "apple" "cheese burger!" "banana"))
I get from Racket letrec: bad syntax (missing body)
. How might I rewrite duplicate
with letrec
?
As you can see in the documentation for letrec
, it has these arguments:
(letrec ([id val-expr] ...) body ...+)
So, you have to add at least one body
form after definitions.
I also replaced cond
with if
(you have only two branches of code), (+ ... 1)
with add1
and improved indentation:
#lang racket
(define (duplicate pos lst)
(letrec ((dup (lambda ([i 0] [lst lst])
(if (= i pos)
(cons (car lst)
lst)
(cons (car lst)
(dup (add1 i) (cdr lst)))))))
(dup)))
Test:
> (duplicate 1 (list "apple" "cheese burger!" "banana"))
'("apple" "cheese burger!" "cheese burger!" "banana")