;;; while-for.rkt ;;; Definition des macros while et for en Scheme #lang racket (provide while for) ; mon for, pas celui de Racket (voir en bas de page) ! (define-syntax while (syntax-rules () ((while test e1 e2 ...) (do () ((not test) (void)) e1 e2 ...)))) (define-syntax for (syntax-rules (from to by in) ((for i from a to b by c e1 e2 ...) (let ((vb b) (vc c)) (do ((i a (+ i vc))) ((> i vb) (void)) e1 e2 ...))) ((for i from a to b e1 e2 ...) (for i from a to b by 1 e1 e2 ...)) ((for x in L e1 e2 ...) (for-each (lambda (x) e1 e2 ...) L)))) ;(define (test-while-for) ; (let ((x 1)) ; (while (< x 10) ; (write x) (display " ") (set! x (+ x 1))) ; (newline) ; (for x from 1 to 10 ; (write x) (display " ")) ; (newline) ; (for x from 1 to 10 by 2 ; (write x) (display " ")) ; (newline) ; (for x in '(a b c d) ; (write x) (display " ")))) ; ;(test-while-for) ; ------------------- le vrai 'for' de Racket ------------------------------------ ; En realite, cette forme (for i from a to b by c e ...) a ete integre au cours ; pour des raisons purement pedagogiques, afin d'illustrer une macro interessante. ; Mais Racket a pris depuis quelques annees les boucles 'for' de Python en les ; adaptant au monde Lisp (ce n'est pas pour rien qu'il se nomme 'Racket'...). ; Il y a plusieurs formes de boucles for, adaptees aux nombres, aux listes, ; aux vecteurs, aux tables de hash-code, etc. On peut meme se construire les ; siennes avec une macro. En voici seulement deux exemples : ; ;(define (somme a b) ; def somme(a,b) : ; (for/sum ([i (in-range a (+ b 1))]) i)) ; return sum(i for i in range(a,b+1)) ; ;(define (produit a b) ; def produit(a,b) : ; (for/product ([i (in-range a (+ b 1))]) i)) ; return --- en Python ils n'aiment pas les produits ? --- ; ;(define ($map f L) ; (for/list ([x (in-list L)]) (f x))) ; ;; attention, j'utilise ici le vrai 'for' de Racket et non celui defini plus haut ! ; ;(define-syntax forever ; (syntax-rules () ; ((forever e ...) (for ([i (in-naturals)]) e ...)))) ; je m'amuse :-) ; ;(define-syntax while ; (syntax-rules () ; ((while test e ...) (forever #:break (not test) e ...)))) ; ; etc.