# Share your favourite macros that you've written!

**URL:** <https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017>\
**Category:** General\
**Tags:** macro\
**Created:** [June 16, 2023, 3:14am UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017 "2023-06-16T03:14:39Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![priime0](https://avatars.discourse-cdn.com/v4/letter/p/ed655f/32.png) [@priime0](https://racket.discourse.group/u/priime0)\
**Post date:** [June 16, 2023, 3:14am UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/1 "2023-06-16T03:14:39Z")

</div>

I'm curious to see the macros others have written. 🙂

---

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [June 16, 2023, 8:31am UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/2 "2023-06-16T08:31:29Z")

</div>

A good place to start: [Syntax Parse Examples](https://docs.racket-lang.org/syntax-parse-example/) which purpose was exactly to answer this question.

A super simple macro I'm using quite often:

```plaintext
(define-syntax-rule (ids->assoc id ...)
  (list (cons 'id id) ...))

```

Usage example:

```plaintext
(define x 3)
(define caps 'CAPS)
(ids->assoc x caps) ; -> '((x . 3) (caps . CAPS))

```

---

<div class="post-metadata">

**Author:** ![Laurent.O](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/laurent.o/32/18_2.png) [@Laurent.O](https://racket.discourse.group/u/Laurent.O)\
**Post date:** [July 5, 2023, 1:30pm UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/3 "2023-07-05T13:30:40Z")

</div>

Another one-liner to define a very simple hygienic threading macro:

```scheme
(define-syntax-parse-rule (with it:id body:expr ...)
  (let* ([it body] ...) it))

```

Usage example:

```scheme
(with it "Hello World"
      (string-downcase it)
      (string-split it)
      (map string->list it)
      (displayln it))
; displays: ((h e l l o) (w o r l d))

```

---

<div class="post-metadata">

**Author:** ![jbclements](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jbclements/32/11_2.png) [@jbclements](https://racket.discourse.group/u/jbclements)\
**Post date:** [July 5, 2023, 6:26pm UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/4 "2023-07-05T18:26:39Z")

</div>

I haven't seen this before... the other threading macros I've used shade gently into point-free mania, this one seems more intuitive. Many thanks!

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [July 5, 2023, 7:51pm UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/5 "2023-07-05T19:51:49Z")

</div>

Not the fanciest ones I've come up with, but maybe my most used: macros to make defining parameters a bit more convienent:

```scheme
#lang racket/base

(require (only-in srfi/235 [boolean make-boolean])
         (for-syntax racket/base syntax/parse))

(provide define-parameter define-boolean-parameter)

; (define-parameter foo 1234) etc
(define-syntax (define-parameter stx)
  (syntax-parse stx
    ((define-parameter name:id initial-value:expr)
     #'(define name (make-parameter initial-value #f (quote name))))
    ((define-parameter name:id initial-value:expr guard:expr)
     #'(define name (make-parameter initial-value guard (quote name))))
    ((define-parameter name:id initial-value:expr guard:expr obj-name:id)
     #'(define name (make-parameter initial-value guard obj-name)))))

; Parameters that always return #t or #f
(define-syntax (define-boolean-parameter stx)
  (syntax-parse stx
    ((define-boolean-parameter name:id)
     #'(define-parameter name #t make-boolean))
    ((define-boolean-parameter name:id initial-value:boolean)
     #'(define-parameter name initial-value make-boolean))
    ((define-boolean-parameter name:id initial-value:boolean obj-name:id)
     #'(define-parameter name initial-value make-boolean obj-name))))

```

(Part of my [`soup-lib`](https://docs.racket-lang.org/soup-lib/index.html) package)

---

<div class="post-metadata">

**Author:** ![shawnw](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/shawnw/32/1031_2.png) [@shawnw](https://racket.discourse.group/u/shawnw)\
**Post date:** [July 6, 2023, 9:49pm UTC](https://racket.discourse.group/t/share-your-favourite-macros-that-youve-written/2017/6 "2023-07-06T21:49:18Z")

</div>

Another one I've been playing with, a version of `case` that uses predicates instead of list membership. Demonstrates using custom syntax classes to break the pattern matching up into manageable pieces, and some more complicated `syntax-parse` patterns involving alternatives and optional matches:

```scheme
(define-syntax (case-when stx)
  (define-syntax-class clause
    #:literals (=>)
    (pattern (~or* (pred:expr => func:expr) (pred:expr body:expr ...+))
      #:fail-when (free-identifier=? #'pred #'else) #f))
  (define-syntax-class else-clause
    #:literals (else =>)
    (pattern (~or* (else => func:expr) (else body:expr ...+))))
  (syntax-parse stx
    [(_ val:expr cl:clause ...+ (~optional else-cl:else-clause))
     #'(let ([obj val])
         (cond
           [(cl.pred obj) (~? (cl.func obj) (~@ cl.body ...))] ...
           (~? (else (else-cl.func obj)) (~? (else else-cl.body ...)))))]))

```

Sample usage:

```scheme
(case-when "abcd"
  [integer? 'integer]
  [symbol? 'symbol]
  [else 'other])

```
