Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable versions of cadr, caddr, etc

I'm wondering how to implement mutable versions of cadr, caddr, and the likes in Racket without defining each one separately? ie. not

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

It seems that for mutable lists or pairs, Racket only supports mcar and mcdr but not the "expanded" versions. Do I need to know and be good at macros to be able to do this?

like image 853
Robert Nail Avatar asked Dec 21 '22 13:12

Robert Nail


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 ([n n] [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))
like image 132
Eli Barzilay Avatar answered Jan 11 '23 02:01

Eli Barzilay


You could do:

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

But there is no real getting around the repetition. Even in the Racket source (look in racket/src/list.c), the repetition is there, albeit prettified a little with C macros.

like image 38
Chris Jester-Young Avatar answered Jan 11 '23 02:01

Chris Jester-Young