# Haskell-inspired define-where macro

**URL:** https://racket.discourse.group/t/haskell-inspired-define-where-macro/672
**Category:** Show & Tell
**Tags:** macro
**Created:** [February 10, 2022, 2:21pm UTC](https://racket.discourse.group/t/haskell-inspired-define-where-macro/672 "2022-02-10T14:21:28Z")
**Posts on this page:** 1
**Page:** 1

<div class="post-metadata">

### Author: ![benknoble](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/benknoble/32/16_2.png) [@benknoble](https://racket.discourse.group/u/benknoble)
#### Post date: [February 10, 2022, 2:21pm UTC](https://racket.discourse.group/t/haskell-inspired-define-where-macro/672/1 "2022-02-10T14:21:29Z")

</div>

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

```scheme
#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](https://racket.discourse.group/t/experiment-with-defines-define-unity/314) 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.
