
Or JSON. In my weather world it seems everyone reads/writes JSON.

@mdmitry94 has joined the channel

Hi all. (now solved, see my response down thread)
I’m trying to shadow a binding using syntax-parameterize
during a call to syntax-local-expand-expression
followed by a call to syntax-local-eval
. I’m doing this because I need to be able to recover a string so that I can run string-append at syntax time, thus I can’t wait for other parts of the expansion process to finish.
Here is a minimal example.
#lang racket
(require racket/stxparam
(for-syntax racket/base
racket/syntax
syntax/parse))
(begin-for-syntax
(define eval-fun (make-parameter eval)))
(define-rename-transformer-parameter node (make-rename-transformer #'node-node))
(define-syntax (sa-node stx)
(syntax-parse stx
[(_ body ...)
(datum->syntax
#'(body ...)
(apply string-append
(map (λ (e) (syntax->datum (local-expand e 'expression #f)))
(syntax-e #'(body ...)))))]))
(define-syntax sa-must (make-rename-transformer #'sa-node))
(define-syntax sa-outer (make-rename-transformer #'sa-node))
(define-syntax (outer stx)
(syntax-parse stx
[(_ body ...)
(define-values (transparent opaque)
(syntax-local-expand-expression
#'(syntax-parameterize ([node (make-rename-transformer #'sa-node)])
(sa-outer body ...))))
(datum->syntax #'(body ...) ((eval-fun) transparent))]))
(define-syntax (node-node stx)
(syntax-parse stx
[(_ body ...)
#'(list 'node body ...)]))
(module+ test-ok
(define out (sa-must "yes! " (outer (node "outer"))))
out
(define in
(syntax-parameterize ([node (make-rename-transformer #'sa-node)])
(sa-must "yes! " (outer (node "inner")))))
in)
#; ; uncomment this to see the error
(module+ test-fail
(begin-for-syntax
(eval-fun syntax-local-eval))
(define out (sa-must "yes! " (outer (node "outer"))))
(define in
(syntax-parameterize ([node (make-rename-transformer #'sa-node)])
(sa-must "yes! " (outer (node "inner")))))
)
I feel like I’m nearly there, and am winding up with syntax-local-expand-expression
producing a value like
(let-values () (#%expression (let-values () (quote "oops"))))
If I try to use syntax-local-eval
or eval-syntax
to reduce the let-values
and the #%expression
I get hit with
; let-values: unbound identifier;
; also, no #%top syntax transformer is bound in the transformer phase
; in: let-values
If I use regular eval
it works and will reduce to "oops"
but only in the original module. I get the same error if I require the form and call it in another module.
Is there some require
for-meta
phase that I can use so that the racket/base
bindings are visible during syntax-local-eval
. Alternately is there a better way to achieve this?
Thanks!

There is a thread from 2018 in this channel that suggests that I probably just need to yank out the value nested in the let-values
and not try to use eval
at all.

The solution is to run that eval
in a static namespace

For example: (begin-for-syntax
(define-namespace-anchor anc-mal)
(define ns-mal (namespace-anchor->namespace anc-mal)))
...
(parameterize ([current-namespace ns-mal])
(eval transparent))

Hi, I want to create an editor for Racket using racket/gui. However, I’m not sure how to evaluate programs written in the editor. Could anyone help me? Thanks. #lang racket/gui
(require racket/gui/base)
(define frame (new frame% [label "Example"]
[width 200]
[height 200]))
(define editor (new editor-canvas% [parent frame]))
(define text (new text%))
(send editor set-editor text)
(send frame show #t)

I recommend looking for the paper “revenge of the son of the lisp machine” which discusses this


seems like racket langserver and now supports autocomplete :party:

Thank you! I’ll read it.

One more question: I would like to provide a button, which, when pressed, inserts placeholders (highlighted in gray) representing required arguments. How can I do this? In particular, I would like to know how to place the cursor in the right position.
#lang racket/gui
(require racket/gui/base)
(define frame (new frame% [label "Example"]
[width 200]
[height 200]))
(define panel (new horizontal-panel% [parent frame]))
(define button-panel (new horizontal-panel% [parent panel][min-width 10]))
(define editor (new editor-canvas% [parent panel][min-width 800]))
(define text (new text%))
(send editor set-editor text)
(new button% [parent button-panel]
[label "check-expect"]
[callback (lambda (button event)
(send text insert "(check-expect")
;(send text insert-box)
(send text insert " ) \n"))])
(send frame show #t)

This is probably the third time I’ve recreated this function in a few different projects. It is the simplest thing that I could come up with that does the job, and I’m sure will fail spectacularly in certain circumstances. Does anyone have a version of this (or better even) in a package? Is functionality like this something that could possibly be added to the standard library (or maybe I’ve missed it?) (define (gunzip-port input-port)
(define-values (pull-in push-out) (make-pipe))
(thread
(lambda ()
(gunzip-through-ports input-port push-out)
(close-output-port push-out)))
pull-in)

So you would trade 7 lines of code for an extra package dependency on your project? Personally, I wouldn’t, but each to their own…

I would guess that a more robust implementation would be more than 7 lines

Is there a difference between in-sequences
and sequence-append
?