sydney.lambda
2019-12-29 15:41:43

Hi :) Finally starting to learn how to use Racket for DSLS, and I’ve completed this tutorial from beautiful racket: https://beautifulracket.com/funstacker/source-listing.html However, one small change I wanted to make was having [stuff] in the source expand to (quotation stuff). I tried redefining #%app for #[ as mentioned here: https://stackoverflow.com/questions/38369817/curly-brackets-to-replace-begin-in-racket/38374850 but no matter what I do, it just appears to treat the parens normally. My best guess is that format-datums is somehow losing the paren-shape metadata? In doing so I also had to stop using the br/quicklang entirely to be able to export #%app without getting “already exported” errors, so I’m guessing that’s just not the right approach for this situation? Any suggestions on how best to go about this without modifying the underlying structure too severely? Thanks :)


soegaard2
2019-12-29 15:53:44

@sydney.lambda The question you linked to is a good starting point. If the match pattern is [_ a-datum:datum] then the template needs to be 'a-datum


soegaard2
2019-12-29 15:54:50

(define-syntax-parser #%app [[_ a-datum:datum ...] #:when (equal? #\[ (syntax-property this-syntax 'paren-shape)) ;; group them in a block #'a-datum])


sydney.lambda
2019-12-29 16:09:32

I just assumed that wasn’t an option due to the difficulty I was having. Inserting the code without change from SO (other than changing the result of the transformer to “test”) just seems to ignore the paren-shape entirely, acting as though it were a regular procedure application: (provide read-syntax handle-args (rename-out [funstacker-module-begin #%module-begin]) (rename-out [PLUS +] [MULT *])) (define-syntax-parser stacker-app [{_ def-or-expr:expr ...} #:when (equal? #\[ (syntax-property this-syntax 'paren-shape)) ;; group them in a block #'"test"] [(_ f:expr arg ...) #:when (not (equal? #\{ (syntax-property this-syntax 'paren-shape))) ;; expand to the old #%app form, from (prefix-in - racket) #'(-#%app f arg ...)]) I also tried renaming #%app to stacker-app and exporting it renamed as #%app, but that just yields: "#%provide: identifier already provided (as a different binding)" at that point I tried forgoing #lang br/quicklang entirely and exporting what was necessary into a #lang base but I just seemed to encounter various different errors and realised I had no idea what I actually should do :/ I believe format-datums is removing the paren-shape metadata somehow, as printing the entire module syntax to debug just yields regular parens. The modification of #%app itself I feel alright with, it’s trying to have this work nicely with the way everything is already plumbed together via br/quicklang is confounding me completely.


soegaard2
2019-12-29 16:19:35

The last clause still uses #\{. I think you can simply remove the #:when … line.


sydney.lambda
2019-12-29 16:21:01

I’m still just getting "#%app: missing procedure expression; probably originally (), which is an illegal empty application" as though they were regular parens, I’m afraid.


soegaard2
2019-12-29 16:21:26

Also the error "#%provide: identifier already provided (as a different binding)" may be saying that there is another #%app being provided already.


soegaard2
2019-12-29 16:22:10

For example if you have (provide (all-from-out racket)) then, since #%app is part of racket that will provide #%app.


sydney.lambda
2019-12-29 16:23:41

I just have the minimal exports: (provide read-syntax (rename-out [funstacker-module-begin #%module-begin]) handle-args (rename-out [PLUS +] [MULT *])) I think it’s something to do with the br/quicklang itself, or format-datums. I get that error about exporting #%app with just those exports.


soegaard2
2019-12-29 16:24:13

Where is format-datums used?


sydney.lambda
2019-12-29 16:25:16

as part of read-syntax: (define (read-syntax path port) (define src-lines (port->lines port)) (define src-datums (format-datums '~a src-lines)) (define module-datum `(module funstacker-mod "funstacker.rkt" (handle-args ,@src-datums))) (datum->syntax #f module-datum))


soegaard2
2019-12-29 16:26:20

To isolate the cause, try defining stacker-app in its own module with a #lang racket.


soegaard2
2019-12-29 16:26:42

Then write a test program in #lang racket that requires that module.


soegaard2
2019-12-29 16:27:09

If that works, then you can look at using it with br/quicklang.


sydney.lambda
2019-12-29 16:30:36

Yup, it works fine that way, I suppose it must have been br/quicklang.


sydney.lambda
2019-12-29 16:31:08

I’ll see if I can just make stacker without using br/quicklang, I’m not sure how much it does for you under the hood. Be a good learning experience, either way. Thanks for helping me isolate the problem :)


soegaard2
2019-12-29 16:31:57

Glad to help. I have never used br/quicklang so I have no idea what it does.