Reputation: 37
I was asked to write a program in racket in order to change the behaviours of arithmetic operators from prefix to postfix. More precisely:
I want this code: (a b +)
to behave like: (+ a b)
I wanted to use define-syntax-rule
in order to change the behaviour of the + operator, but I have one problem, while using define-syntax-rule
we write at first the name of our macro, and after that we write the arguments.
My question: Is there any way to write the arguments at the beginning and the name at last in racket functions?
Upvotes: 1
Views: 98
Reputation: 22332
The easiest way to accomplish this is to create your own #%app
macro. Since you are essentially creating a new language here, you'll want two modules: a 'lang' module that defines your language, and a 'use' module, for the program you want to write in that language. This could be done with two files, or one file using submodules.
Here, I'll show it to you using two files:
lang.rkt
#lang racket
(provide (except-out (all-from-out racket)
#%app)
(rename-out [-app #%app]))
(require syntax/parse/define)
(define-syntax-parse-rule (-app args ... proc)
(#%app proc args ...))
use.rkt
#lang s-exp "lang.rkt"
(3 2 +) ; => 5
Note though that this only changes function calls, not other forms. So:
use2.rkt
#lang s-exp "lang.rkt"
(define x 42)
(2 x *) ; => 84
Edit:
To explain what's happening in lang.rkt
. It's taking the racket
language, and re-exporting all of it, except the #%app
macro. (For reference, all function applications in racket (f args ...)
get expanded to (#%app f args ...)
.)
For the #%app
macro, we define another macro -app
, which moves the function call from the end to the start, and the uses Racket's #%app
macro. We then rename -app
to #%app
on export.
Section 5.1 of this paper gives you an outline of the same thing, but to turn Racket into a lazy language.
Upvotes: 1