I've noticed that Gambit seems to require all internal definitions to be at the top of a body. It will give "Ill-placed 'define'" otherwise. Other Scheme implementations seem to allow interleaving definitions and expressions as long as the last form of a body is an expression.
The reason I care about this is that sometimes test code in Clojure involves wrapping an entire file in a top-level function which is called to run the tests. If there are assert statements between function definitions, I will cause a "Ill-placed 'define'" error. This isn't really common, but it is done in the ClojureScript tests for example.
In some cases I imagine I could tree-walk the forms and lift any nested definitions to the top-level to manually forward-declare them, and then replace the internal definitions with set!... but I'd like to avoid such non-local code transformations if possible.
Another option would be to unwind all lets and lambdas so each body only can contain one expression, such that
(let () 1 (define two 2) two) => (let () 1 (let () (two 2) two))
Not sure off-hand if this approach would have any downsides w.r.t. the compiled code?
Are there any other avenues I could explore to allow this interleaving to be expressed in Gambit?