Skip to content

Instantly share code, notes, and snippets.

@dandrake
Last active July 26, 2025 19:22
Show Gist options
  • Select an option

  • Save dandrake/032dcc0c9f7ac455a799c8fecca02717 to your computer and use it in GitHub Desktop.

Select an option

Save dandrake/032dcc0c9f7ac455a799c8fecca02717 to your computer and use it in GitHub Desktop.
macro for defining constant / immutable variables in Racket

A macro that creates constants in Racket

Inspired by this Racket discourse post I tried writing a macro that defines bindings that work like constants in Racket.

Note that the solution here handles using set!; you can't prevent shadowing or redefining these variables -- see the Discourse thread.

#lang racket
(require (for-syntax syntax/parse))
(define-syntax (define/constant stx)
(syntax-parse stx
[(_ constant:id value:expr)
#:with module-path (datum->syntax stx 'racket/base)
#:attr module-name (datum->syntax stx (gensym))
#:with require-expr
(datum->syntax stx
`(require (prefix-in constants:
(quote ,(attribute module-name)))))
#`(begin
(module module-name module-path
(provide (all-defined-out))
(define constant value))
require-expr)]))
(define/constant foo "foo via define/constant")
(define/constant bar "bar via the macro")
constants:bar
constants:foo
;; since : has no special meaning for Racket identifiers, you can
;; do a kind of namespacing:
(define/constant db:thing1 "something related to the database")
(define/constant db:thing2 "another thing related to the database")
(define/constant ui:thing1 "some UI-related constant")
(list constants:db:thing1 constants:db:thing2 constants:ui:thing1)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment