tommaisey
tommaisey

Reputation: 459

Destructuring records in Scheme

I'm learning Scheme, coming from a C/C++ background. I'm quite used to putting related values together into structs, and I've found Scheme's records work quite well for this.

If find myself doing this quite often to avoid visual noise in function bodies:

(define (f pt z)
  (let*
    ((x (point-x pt))
     (y (point-y pt))
     (d (* x y z)))
   ...)

Where pt is a point record. Is there a shorter way to bind/destructure the fields of a record? Ideally this would work inside a let binding, but I can't figure out a way to write a macro that would accomplish this, or if that's even possible.

Upvotes: 3

Views: 558

Answers (3)

tommaisey
tommaisey

Reputation: 459

I have got better at Scheme macros since I asked this question, and I'm currently using this macro:

(define-syntax derecord
    (syntax-rules ()
      ((_ record ([name record-accessor] ...) body-forms ...)
       (let ([name (record-accessor record)] ...)
     body-forms ...))))

Which gives syntax like this:

(derecord my-rec ([x my-rec-x] [y my-rec-y])
    (* x y))

It's only slightly nicer than doing it manually in let, but I thought I'd post it for any other beginners like me.

Upvotes: 0

Chris Vine
Chris Vine

Reputation: 727

If you are using chez scheme, I suggest the port of Alex Shinn's match here: https://github.com/fedeinthemix/chez-matchable . You can match against chez's r6rs records (amongst many other things) with it.

Upvotes: 1

Óscar López
Óscar López

Reputation: 236034

In Racket, we can use match to destructure the fields of a record. It's debatable if this is a nicer way to do it...

(define (f pt z)
  (match pt
    [(point x y)
     (let ([d (* x y z)])
       ...)]))

Upvotes: 4

Related Questions