
Hi! Stupid question, but how do I append two datums

Like, how do I turn 'pine
and 'apple
into 'pineapple

Is the best way to do it just (string->datum (string-append (datum->string 'pine) (datum->string 'apple)))
?

they’re “symbols”, not “datums”

but yes, you have to use symbol->string
and string->symbol
, though if you’re using them as syntax identifiers, you can use format-id
.

How can I then use that identifier from format-id
? In my case, I’m using it to generate a function name and I have the arguments as syntax-objects

I thought I could do e.g. (let ([id (format-id <args>)]) (list->syntax (id <stx1> <stx2>)))
, but it doesn’t seem like there’s such a list->syntax function

Are you using syntax/parse
?

Yes

In reality, <stx1>
is #'var
where var
is a pattern variable

You can use #:with id (format-id <args>)
as a pattern directive, then #'(id <stx1> <stx2>)
.

Oh! Thanks

Or, if you want the ordinary, non-pattern binding, #`(#,(format-id <args>) <stx1> <stx2>)

Or, if you really do want to do it manually, (datum->syntax #'here (list (format-id <args>) <stx1> <stx2>))
, but I think using syntax
or quasisyntax
is a better bet.

@hazel.r.pearson has joined the channel

So, when I make this identifier with format-id
I have to provide
it, whereas if I call it directly I don’t. Is there any way to not have to provide the identifier?

@brendan I don’t know what you mean. Can you make a MCVE? https://stackoverflow.com/help/mcve

yeah, sorry

In point-lang.rkt
#lang racket
(require syntax/parse/define (for-syntax racket/syntax))
(provide #%module-begin #%datum #%app define/point set-field)
(struct point (x y) #:mutable)
(define-syntax-parser set-field
[(_ p field val) #`(#,(format-id #'field "set-point-~a!" (syntax-e #'field)) p val)])
(define-syntax-parser define/point
[(_ p:id x:number y:number) #'(define p (point x y))])
in point-test.rkt
#lang s-exp "point-lang.rkt"
(define/point my-point 1 2)
(set-field my-point x 1)

@lexi.lambda this is pretty much what I’m trying to do

I think your first argument to format-id
is wrong, since you want the field mutator to have the lexical context of point-lang.rkt
, not point-test.rkt
. Try using #'here
instead of #'field
for the lexical context argument.

oh… that makes perfect sense

(There is nothing magical about the name “here
” in #'here
, it’s just a piece of syntax that has the lexical context of the containing module.)

@brendan Also, FWIW, you probably want to put the :id
syntax class on field
, since otherwise (set-field my-point "x" 1)
will fail with a compile-time contract violation blaming point-lang.rkt
.

Oh, I thought id
actually checked that it was a valid identifier

identifier?
is just (and/c syntax? (lambda (stx) (symbol? (syntax-e stx))))
.

Okay, that makes more sense

Thanks for the help Alexis!