Does Racket have any grammar-based fuzzing utilities? I'm probably going to play around with this either way, but if there is an existing solution I'll quit after I've had my fun. If, however, people think Racket could use something like this I may attempt to make it into a usable package.
I'm thinking specifically about generating inputs for Quickcheck, but such a fuzzer might have other uses.
For example, given this grammar:
(struct tree (left right) #:transparent)
(define-grammar tree-grammar
[Leaf (:choose-integer -9999 9999)]
[Subtree #'(tree Node Node)]
[Node #:max-nesting 10
(:weighted-choice
[1 Leaf]
[5 Subtree])])
Then (tree-grammar 'Subtree) might generate #'(tree 1 (tree 2 3)) as one of many possibilities.
An important feature that I haven't seen yet is tracking/scoping identifiers. There are times when we want to generate any arbitrary identifier, and other times when we want to use an existing identifier that we know is in scope. For example, if we were fuzzing `let` we might have
(define-grammar let-grammar
[Root #'(let ([LetId LetVal]
...)
LetBody)]
[LetId (:choose-identifier)]
; TODO ...
)
And somehow we want to say that LetBody can and should use the enclosing LetIds, but I don't immediately see a great way to communicate that. It might be possible to have something like (:choose-bound LetId) which would generate a LetId that is known to be in scope.