Variable versions of cadr, caddr, etc.

I am wondering how to implement mutable versions of cadr, caddr and the like in Racket without defining each separately? i.e. not

(define (mcadr exp) (mcar (mcdr exp))) 

For mutable lists or pairs, it seems that Racket only supports mcar and mcdr, but not "extended" versions. Do I need to know and be good at macros to do this?

+4
source share
2 answers

Here's a macro solution:

 #lang racket/base (require racket/mpair (for-syntax racket/base)) (define-syntax (define-combinations stx) (syntax-case stx () [(_ n) (integer? (syntax-e #'n)) (let ([n (syntax-e #'n)]) (define options (list (cons "a" #'mcar) (cons "d" #'mcdr))) (define (add-options r) (apply append (map (λ (opt) (map (λ (l) (cons (string-append (car opt) (car l)) (list (cdr opt) (cdr l)))) r)) options))) (define combinations (cdddr (let loop ([nn] [r '(("" . x))]) (if (zero? n) r (append r (loop (sub1 n) (add-options r))))))) (define (make-name combo) (let ([s (string->symbol (string-append "mc" (car combo) "r"))]) (datum->syntax stx s stx))) (with-syntax ([(body ...) (map cdr combinations)] [(name ...) (map make-name combinations)]) #'(begin (define (name x) body) ...)))])) (define-combinations 4) (mcaddr (mlist 1 2 3 4 5)) 
+9
source

You can do:

 (define mcaar (compose mcar mcar)) (define mcadr (compose mcar mcdr)) ;; ... (define mcddddr (compose mcdr mcdr mcdr mcdr)) 

But there is no repetition of repetition. Even in the Racket source (see racket/src/list.c ), there is repetition, albeit a bit embellished with C macros.

+2
source

All Articles