Answering your questions:
define
can only be used in certain ways, as mandated by the specification. What you want to do isn't covered by the specification, hence the error. As you know,define
assigns a name to the value of an expression, it's just that you can't directly create internal definitions in its context.- But there are other expressions that allow creating new bindings in this context. IMHO
foo2
is the best option here, and it's idiomatic, too. And ifbar
were a recursive definition, you could useletrec
.
But if loosing a bit of syntactic sugar bothers you (because of the way procedures are defined inside a let
expression), then try using local
, it'll work in Racket:
(define foo
(local [(define (bar n) (+ n n))]
(bar 1)))