Haskell-inspired define-where macro

Here's a little Haskell-inspired macro I whipped up for define:

#lang racket

(require (only-in racket/base [define def]))

(require syntax/parse/define)

(define-syntax-parser define
  [(_ head e:expr #:where body:expr ...) #'(def head (begin body ... e))]
  [(_ head . body) #'(def head . body)])

(define (foo x)
  (complex x)

  #:where

  (define (complex y)
    (something-complicated)
    (add1 x))
  (define (something-complicated)
    (void)))

(module+ main
  (foo 123))

Note that the result expression before #:where is constrained to a single expression to encourage functional style; imperative blocks need explicit begin or begin0 (though the #:where clause is not limited to definitions, so you can do some confusing side-effects there as well).

This combined with Experiment with defines: define unity makes me wonder about packages like fancy-app and its cousins that co-operate to stack features (if I'm not mistaken). I seem to want to augment define in the same way, rather than always adding a new define/foo clause.

4 Likes