In Racket, you can do this with modules. You can create a module that re-exports the entire Racket language except Racket lambda and exports your new macro called lambda . I will show one way to arrange the code.
The foo-lambda module defines and exports the foo-lambda form, which creates procedures that print "foo \ n" when applied.
(module foo-lambda racket (define-syntax-rule (foo-lambda formals body ...) (lambda formals (displayln "foo") body ...)) (provide foo-lambda))
The racket-with-foo-lambda module relays the entire Racket language, except that it provides foo-lambda under the name lambda .
(module racket-with-foo-lambda racket (require 'foo-lambda) (provide (except-out (all-from-out racket) lambda) (rename-out [foo-lambda lambda])))
Now you can write a module in this "new language":
(module some-program 'racket-with-foo-lambda (define f (lambda (x) x)) (f 2)) (require 'some-program)
Note that this does not change the version of Racket lambda , and other Racket formats still use the Racket lambda binding. For example, if you rewrote the definition of f above as (define (fx) x) , then Racket define would expand to use Racket lambda and you would not get a printout of "foo".
You can connect extensions: each extension is defined in a module that imports a previous version. For example, your bar-lambda module imports the foo-lambda module, etc.
A racket does this internally, essentially. The compiler only understands lambda with positional arguments, but the Racket language has lambda that supports both positional and keywords. The Racket language implementation has a module that replaces the built-in lambda and #%app (implicitly used to process the syntax of functional applications) with versions that process keyword arguments.
Ryan culpepper
source share