racket
Recursion
Buscar..
Utilizando define
#lang racket
(define (sum-of-list l)
(if (null? l)
0
(+ (car l)
(sum-of-list (cdr l)))))
(sum-of-list '(1 2 3 4 5)) ;; => 15
Usando let-rec
#lang racket
(letrec ([sum-of-list (λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))])
(sum-of-list '(1 2 3 4 5)))
;; => 15
Es posible escribir funciones recursivas entre sí con letrec
:
#lang racket
(letrec ([even? (λ (n) (if (= n 0) #t (odd? (sub1 n))))]
[odd? (λ (n) (if (= n 0) #f (even? (sub1 n))))])
(list (even? 3)
(odd? 5)))
;; => '(#f #t)
Usando una let con nombre
Una forma normal de let
une cada valor a su identificador correspondiente, antes de ejecutar el cuerpo. Con una " let
nombre", el cuerpo puede volver a ejecutarse recursivamente, pasando un nuevo valor para cada identificador.
#lang racket
(let sum-of-list ([l '(1 2 3)])
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
;; => 15
Es común usar rec
como el nombre para let, que da:
#lang racket
(let rec ([l '(1 2 3 4 5)])
(if (null? l)
0
(+ (car l) (rec (cdr l)))))
;; => 15
Usando rec
#lang racket
(require mzlib/etc)
((rec sum-of-list
(λ (l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l))))))
'(1 2 3 4 5))
;; => 15
;; Outside of the rec form, sum-of-list gives an error:
;; sum-of-list: undefined;
;; cannot reference an identifier before its definition
Esto es similar a define
, pero el identificador de sum-of-list
no es visible fuera del formulario de rec
.
Para evitar el uso de un λ
explícito, es posible reemplazar la sum-of-list
con (sum-of-list args ...)
:
#lang racket
(require mzlib/etc)
((rec (sum-of-list l)
(if (null? l)
0
(+ (car l) (sum-of-list (cdr l)))))
'(1 2 3 4 5))
;; => 15
Usando funciones de orden superior en lugar de recursión
Es una práctica común utilizar funciones de orden superior en lugar de recursión, si hay una función de orden superior que expresa el patrón de recursión correcto. En nuestro caso, la sum-of-numbers
se puede definir usando foldl
:
#lang racket
(define (sum-of-numbers l)
(foldl + 0 l))
(sum-of-numbers '(1 2 3 4 5)) ;; => 15
Es posible llamar a foldl
directamente en la lista:
#lang racket
(foldl + 0 '(1 2 3 4 5)) ;; => 15