I ran into a series of confusing Racket things today. Although I've fixed my code, I'm looking for insight. Clearly there are things I don't understand about scribble/srcdoc, and maybe macros in general.
I have a macro called define/contract/doc. It lets me do things like this: (define/contract/doc (test #:number [number 75.2]) (->i () (#:number [number number?]) [returns any/c]) @{Returns what you pass in for #:number. Defaults to 75.2} number) It has worked fine for almost a year. But today, I discovered that when I define a function with a default parameter value that happens to include a decimal number (i.e. 75.2 above), I get a cryptic error when requiring in the srcdoc submodule. I'll post the macro definition in a moment, but first let me mention that on the Windows machine where my co-worker first discovered this bug, the error was presented without a stacktrace. This was it: -: contract violation expected: number? given: #f argument position: 1st other arguments...: 2 context...: *Puzzle #1. *I don't usually develop on Windows, so can someone tell me if there's something special I'm supposed to do to get more context to print out? Note: Even in the Racket REPL, I couldn't get a backtrace. Using errortrace changed nothing. I'm on Racket 7.4, btw. It was only after poking, prodding, and simplifying for an hour that we extracted a minimal reproduction of the bug and figured out that the decimal number was causing the problem. The lack of stacktrace led to a lot of guesswork. I would have been at a loss, but I happened to switch to my Mac, where (luckily!) the error printed with a better stacktrace: -: contract violation expected: number? given: #f argument position: 1st other arguments...: 2 context...: /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/racket.rkt:227:2: typeset-atom /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/racket.rkt:471:8 /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/racket.rkt:322:2: gen-typeset /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/private/manual-proc.rkt:549:6 /Applications/Racket v7.4/collects/racket/private/map.rkt:259:4: loop /Applications/Racket v7.4/collects/racket/list.rkt:586:2: append-map /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/private/manual-proc.rkt:316:2: do-one /Applications/Racket v7.4/collects/racket/private/map.rkt:259:4: loop /Applications/Racket v7.4/collects/racket/list.rkt:586:2: append-map /Applications/Racket v7.4/share/pkgs/scribble-lib/scribble/private/manual-proc.rkt:212:0: *defproc13 (submod "/Users/thoughtstem/Dev/test/test.rkt" srcdoc): [running body] temp37_0 for-loop run-module-instance!125 perform-require!78 for-loop ... This informed me that the problem was related to typeset-atom, which in turn helped me to make slightly more educated guesses about how to fix the problem. *Puzzle #2*. If you save the snippet below into a file called test.rkt, you can reproduce the error and/or my fixes with something like racket -e "(require (submod \"./test.rkt\" srcdoc))". Why does the datum->syntax fix the problem? After skimming the srcdoc code, I suspect some line-number information needs to be present on the syntax being typeset.... Why this only matters for numbers with decimals is still a mystery. #lang at-exp racket (require (for-syntax syntax/parse)) (define-syntax (define/contract/doc stx) (define defaults '(75) ;Works #; '(75.2) ;Breaks #; (datum->syntax stx '(75.2) stx) ;Works, and is essentially the way we fixed it. #; (datum->syntax stx '(75.2)) ;Breaks, and is roughly what we had in production -- without the hardcoded 75.2, obviously. ) (define ret (syntax-parse stx ([_ (f-name args ... ) contract doc body ...] #`(begin (require scribble/srcdoc) (provide (proc-doc f-name contract #,defaults doc)) (define (f-name args ...) body ...))))) ret) (define/contract/doc (test #:number [number 75.2]) (->i () (#:number [number number?]) [returns any/c]) @{Returns what you pass in for #:number. Defaults to 75.2} number) *Puzzle #3*. What's the appropriate code to "blame" here? Is this some kind of noob mistake on my part (i.e. advanced Racket macrologists would have known to use datum->syntax appropriately and never would have run into the problem in the first place)? Is this a bug in srcdoc? Is it both? *(Bonus) **Puzzle #4.* How would you have debugged this? Was there anything I could have done to localize the problem more quickly? -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/58c6965f-a446-4812-bb04-1afb4fd7e798%40googlegroups.com.