brendan
2018-1-14 01:32:01

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


brendan
2018-1-14 01:32:22

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


brendan
2018-1-14 01:33:22

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


lexi.lambda
2018-1-14 01:33:39

they’re “symbols”, not “datums”


lexi.lambda
2018-1-14 01:33:50

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.


brendan
2018-1-14 01:45:33

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


brendan
2018-1-14 01:46:37

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


lexi.lambda
2018-1-14 01:51:37

Are you using syntax/parse?


brendan
2018-1-14 01:51:56

Yes


brendan
2018-1-14 01:52:29

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


lexi.lambda
2018-1-14 01:52:38

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


brendan
2018-1-14 01:52:51

Oh! Thanks


lexi.lambda
2018-1-14 01:53:12

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


lexi.lambda
2018-1-14 01:54:22

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
2018-1-14 02:06:24

@hazel.r.pearson has joined the channel


brendan
2018-1-14 02:25:57

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?


lexi.lambda
2018-1-14 02:29:23

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


brendan
2018-1-14 02:29:31

yeah, sorry


brendan
2018-1-14 02:35:31

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)


brendan
2018-1-14 02:36:24

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


lexi.lambda
2018-1-14 02:37:19

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.


brendan
2018-1-14 02:37:52

oh… that makes perfect sense


lexi.lambda
2018-1-14 02:37:53

(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.)


lexi.lambda
2018-1-14 02:40:02

@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.


brendan
2018-1-14 02:40:33

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


lexi.lambda
2018-1-14 02:41:07

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


brendan
2018-1-14 02:41:14

Okay, that makes more sense


brendan
2018-1-14 04:34:58

Thanks for the help Alexis!