laurent.orseau
2021-1-2 11:39:06

In scribble doc, is it possible to link to an identifier like with @racket[some-id], but actually display another identifier? More precisely, I import (require (prefix-in rkt (only-in racket/base define))) , and I want to write > …, just like racket’s @racket[rkt:define] but I want to render > …, just like racket’s define


selcukahmed
2021-1-2 12:49:16

@selcukahmed has joined the channel


soegaard2
2021-1-2 13:15:08

Take a look at make-element-id-transformer


kellysmith12.21
2021-1-2 13:25:10

Would make-variable-id (<https://docs.racket-lang.org/scribble/scheme.html?q=make-element-id-transformer#%28def._%28%28lib._scribble%2Fracket..rkt%29._make-variable-id%29%29|link to doc>) also be appropriate?


soegaard2
2021-1-2 13:27:25

In this case no - since define is a special form and not a variable. For functions it would be fine.


laurent.orseau
2021-1-2 13:30:57

Thanks! That doesn’t look as straightforward as I hoped :smile:


kellysmith12.21
2021-1-2 13:31:40

It would be nice if there were a library form for this.


soegaard2
2021-1-2 14:45:34

Here is a more complete solution. In order for @racket[rkt:id] to render as @racket[id], we need to import id without prefix. So I think one needs to put the code below in a separate module and then export all identifiers that begin with rkt:

#lang scribble/manual @(require (for-label racket)) @(require (for-syntax racket/base scribble/manual syntax/parse racket/syntax scribble/racket)) @(require (for-syntax doc-coverage racket/set)) @(require scribble/racket) @(define-syntax (define-elements-for-prefixed-imports stx) (syntax-parse stx [(_ prefix modname) (define all-exports ; make sure each identifer occurs once only (set-&gt;list (list-&gt;set (module-&gt;all-exported-names (syntax-e #'modname))))) (define (format-sym id) (format-id stx "~a" id #:source stx)) (define (format-pre:id id) (format-id stx "~a:~a" #'prefix id #:source stx)) (define (format-elm:id id) (format-id stx "~a:~a" #'elm1234 id #:source stx)) (with-syntax* ([(id ...) (map format-sym all-exports)] [(pre:id ...) (map format-pre:id all-exports)] [(elm:id ...) (map format-elm:id all-exports)]) (syntax/loc stx (begin (begin (define elm:id @racket[id]) (define-syntax pre:id (make-element-id-transformer (λ _ #'elm:id)))) ...)))])) @(define-elements-for-prefixed-imports rkt racket/base) @section{Foo} @racket[rkt:define]


laurent.orseau
2021-1-2 14:51:49

Wow, thanks! That’s even more complicated than I imagined :smile:


soegaard2
2021-1-2 14:52:55

Yeah - I underestimated it too.


laurent.orseau
2021-1-2 15:11:44

What’s the correct way (pointer appreciated) with rackunit to check compile time error messages? (I’m writing a macro that should provide good error messages and not mix up the different possible messages)


laurent.orseau
2021-1-2 15:12:50

I can imagine doing a dynamic require or an eval, but there must be something more standard somewhere



laurent.orseau
2021-1-2 15:26:38

Wonderful, precisely what I was looking for! Thanks @popa.bogdanp!


laurent.orseau
2021-1-2 15:31:34

Ouch, it doesn’t seem to test define properly: #lang racket (require syntax/macro-testing rackunit) (check-exn #rx"aaa" (λ () (convert-syntax-error (define x 3)))) This catches: "define: not allowed in an expression context" :disappointed:


laurent.orseau
2021-1-2 15:33:22

I guess I can wrap it inside a (let () ...) but that doesn’t sound right


samth
2021-1-2 15:38:49

There are some places in the docs that do this, so you could look for the source


laurent.orseau
2021-1-2 15:40:08

Do you happen to remember such an identifier by any chance?


sorawee
2021-1-2 16:00:36

laurent.orseau
2021-1-2 16:17:09

Too bad is still not accepted


sorawee
2021-1-2 17:08:00

The PR-er seems to delete the forked repo, so I don’t know if they want to continue working on it. I just asked in the PR if they are OK with someone taking it over.


sorawee
2021-1-2 17:08:47

Ah:

> Happy to take this on. I have a new year’s resolution to get back to some > of the open source work I had that piled up during the pandemic :slightly_smiling_face:. I’ll reassociate myself with this PR and write up the changes. Nice :slightly_smiling_face:


soegaard2
2021-1-2 17:16:50

Hi all. I have added two sections to the macro tutorial. As before comments on contents, grammar, exposition are needed. Section “4. Syntax objects: Representing program fragments” and section “5. Exploring syntax objects” are new.


sorawee
2021-1-2 17:26:18

This is very nice!


sorawee
2021-1-2 17:26:52

I’ve never seen the word “enrichen” before. I google-d it and it looks like “to enrich” is more idiomatic.


soegaard2
2021-1-2 17:35:02

Noted.


sorawee
2021-1-2 17:37:18

“During the expansion pass macros … rewrite program fragments” << should have a comma between “pass” and “macros”


soegaard2
2021-1-2 17:39:03

Added.


sorawee
2021-1-2 17:43:03

High level comment: can we simplify section 3 by skipping read and expand and use read-syntax and expand-syntax right away?


sorawee
2021-1-2 17:44:13

I don’t know who the targeted audience is, but to me, I guess it would be people who can write simple macros and now want to understand macros better. The read vs read-syntax would be a distraction for these audiences IMO, and might cause them to feel “scared” (what the heck is namespace-syntax-introduce?!?)


sorawee
2021-1-2 17:44:34

I feel it introduces more questions than answers


soegaard2
2021-1-2 17:48:10

> … people who can write simple macros and now want to understand macros better. I like this way of putting it.

And you are right about expand-syntax. I attempted to preface the last part of the experiment with for the second reading only , but I think you are right that it is better to leave it out. Or perhaps return to it in a later section after namespace-syntax-introduce has been discussed.


jjsimpso
2021-1-2 17:55:19

I’m trying to include code written in a custom language into another file at compile-time. This is what I have at the moment(see below), which compiles without errors but doesn’t appear to include the contents of “elf”. Expanding the include line shows the following error: “string::1: include/reader: read error (Encountered parsing error near #f (token ’no-tokens) while parsing #<path:/home/jonathan/git/identify/src/magic/elf> [line=#f, column=#f, offset=#f]) in: (include/reader “elf” magic-read-syntax-raw)”.

Am I on the correct path or am I misunderstanding what include/reader is supposed to do? My magic-read-syntax-raw returns a syntax object without the normal module wrapping. The “elf” file isn’t a racket file. It is written in the file command’s “magic” DSL, which I’ve written a racket implementation of. #lang racket (require (for-syntax magic/reader)) (module rules magic/expander (include/reader "elf" magic-read-syntax-raw)) (require 'rules)


soegaard2
2021-1-2 18:02:33

Step 1 must be to check that magic-read-syntax-raw can read the contents of “elf” without errors. Does (magic-read-syntax-raw "elf" (open-input-string "the contents of elf here")) work as expected?


soegaard2
2021-1-2 18:04:20

Does magic-read-syntax-raw return a syntax object?


jjsimpso
2021-1-2 18:19:32

Yes, magic-read-syntax-raw appears to be working as I expect it to: reader.rkt&gt; (define inport (open-input-file "/home/jonathan/git/identify/src/magic/elf")) reader.rkt&gt; (magic-read-syntax-raw "/home/jonathan/git/identify/src/magic/elf" inport) '(#&lt;syntax:/home/jonathan/git/identify/src/magic/elf:17:0 (named-query (name-line (offset 0) (name-type "name") elf-mips) (level) (line (offset 0) (type (numeric "lelong" (nummask (op "&amp;") 4026531840))) (test (numtest 0)) (message "MIPS-I")) (level) (line (offset 0) (type (numeric "lelong" (nummask (op "&amp;") 40...&gt; #&lt;syntax:/home/jonathan/git/identify/src/magic/elf:30:0 (named-query (name-line (offset 0) (name-type "name") elf-sparc) (level) (line (offset 0) (type (numeric "lelong" (nummask (op "&amp;") 16776960))) (test (numtest 256)) (message "V8+ Required,")) (level) (line (offset 0) (type (numeric "lelong" (nummask (op...&gt; #&lt;syntax:/home/jonathan/git/identify/src/magic/elf:39:0 (named-query (name-line (offset 0) (name-type "name") elf-pa-risc) (level) (line (offset 2) (type (numeric "leshort")) (test (numtest 532)) (message "2.0")) (level) (line (offset 0) (type (numeric "leshort")) (test (numtest "&amp;" 8)) (message "(LP64)")))&gt; #&lt;syntax:/home/jonathan/git/identify/src/magic/elf:43:0 (named-query (name-line (offset 0) (name-type "name") elf-le) (level) (line (offset 16) (type (numeric "leshort")) (test (numtest 0)) (message "no file type,")) (level) (line (offset 16) (type (numeric "leshort")) (test (numtest 1)) (message "relocatabl...&gt; #&lt;syntax:/home/jonathan/git/identify/src/magic/elf:298:0 (query (line (offset 0) (type (string8 "string")) (test (strtest "\u007FELF")) (message "ELF")) (level) (line (offset 4) (type (numeric "byte")) (test (numtest 0)) (message "invalid class")) (level) (line (offset 4) (type (numeric "byte")) (test (numtes...&gt;) reader.rkt&gt;


jjsimpso
2021-1-2 18:21:14

Although, now that I look at it again, that appears to be a list of syntax objects instead of a syntax object.


soegaard2
2021-1-2 18:21:49

That’s probably it.


jjsimpso
2021-1-2 18:22:50

Shouldn’t strip-context here be returning a syntax object: (define (magic-read-syntax-raw path port) (define parse-tree (stx-cdr (stx-cdr (parse path (make-tokenizer port))))) ;(eprintf "parse tree = ~a" parse-tree) (strip-context parse-tree))


jjsimpso
2021-1-2 18:23:05

?


soegaard2
2021-1-2 18:24:48

That’s my expectation as well.


jjsimpso
2021-1-2 18:26:40

I’m not sure what the problem is then. Am I interpreting that output above correctly? That is a list of syntax objects and not a syntax object, right? If so maybe I can just do something different with or instead of syntax-context.


soegaard2
2021-1-2 18:27:40

&gt; (syntax? '(1 2 3)) #f


soegaard2
2021-1-2 18:28:42

You could make into a syntax object: (with-syntax ([(x ...) tree) #'(x ...))


soegaard2
2021-1-2 18:28:54

Or maybe a call to datum-&gt;syntax is better?


soegaard2
2021-1-2 18:29:15

I think, it leaves any syntax objects in a list untouched.


jjsimpso
2021-1-2 18:29:34

It appears that strip-context will accept non-stx. So yes, I think datum-syntax may be better.


soegaard2
2021-1-2 18:30:53

Just making sure, we are not talking past each other: (datum-&gt;syntax #'here (strip-context parse-tree)))


jjsimpso
2021-1-2 18:34:03

Hmm. We are on the same page here, but I still get the same error when I expand the include line. magic-read-syntax-raw is returning a syntax object now though. If this should be workable in theory, I will keep experimenting with it.


jjsimpso
2021-1-2 18:34:33

This is what I have now: (define (magic-read-syntax-raw path port) (define parse-tree (stx-cdr (stx-cdr (parse path (make-tokenizer port))))) ;(eprintf "parse tree = ~a" parse-tree) (datum-&gt;syntax #'here (strip-context parse-tree)))


soegaard2
2021-1-2 18:34:33

The idea looks fine to me.


soegaard2
2021-1-2 18:34:48

Using include/reader that is.


jjsimpso
2021-1-2 18:35:31

Ok, great. Thanks very much for your help. I will keep tinkering with it.


soegaard2
2021-1-2 18:35:52

Is token 'no-tokens) part of the output of your reader, or does it come from include/reader ?


jjsimpso
2021-1-2 18:37:06

I’m not entirely sure because the parse function is from #lang brag. I was thinking it was probably from include/reader but I could be wrong.


jjsimpso
2021-1-2 18:38:14

I get different errors from include/reader if it can’t find the file or if I use the wrong read-syntax function though.


soegaard2
2021-1-2 18:39:53

In that case I think it comes from the parser.

Maybe check how the input for the reader looks like, when include/reader is involved. Just to be sure. For example, insert an displayln in your reader to print its input.


jjsimpso
2021-1-2 18:40:36

brag has a token function, so it could be the parse function. But I don’t get the error from magic-read-syntax-raw in isolation.


soegaard2
2021-1-2 18:42:15

Btw - line=#f, column=#f, offset=#f]) shows that line numbers aren’t counted. You can use (port-count-lines! port) to turn it on.


jjsimpso
2021-1-2 18:43:44

hmm, my make-tokenizer function does do that, so I’m not sure why they aren’t being counted. unless the file really isn’t being read or something.


gknauth
2021-1-2 19:36:54

@alama got your newsletter, bought Remember because it was written in Racket, would love to see a write-up on developing iOS/Android apps in Racket


spdegabrielle
2021-1-2 19:40:06

@popa.bogdanp did a write-ups discussing macOS and iOS https://defn.io/page/2/\|https://defn.io/page/2/


popa.bogdanp
2021-1-2 19:59:17

Thanks for buying Remember! And thanks to @alama for the shout-out! Like @spdegabrielle mentioned, I did a couple write-ups about embedding Racket into native apps on https://defn.io/2020/01/04/remember-internals/\|macOS and https://defn.io/2020/01/05/racket-on-ios/\|iOS on that blog. I’m also planning to do another one on embedding Racket CS at some point. Remember is source-available so if you’re curious about its internals, you can find the code https://github.com/bogdanp/remember\|here.


laurent.orseau
2021-1-2 20:08:35

In syntax-parse, the error message for a #:fail-when of a syntax-class is tailored to the enclosing macro name, which is pretty cool. But is there a way to make it ‘bounce’ to a super enclosing macro? syntax/loc doesn’t help here (afaict).


sorawee
2021-1-2 20:10:39

Does #:context help?


sorawee
2021-1-2 20:12:31

#lang racket (require (for-syntax racket/base syntax/parse)) (begin-for-syntax (define-syntax-class aclass (pattern x #:fail-when (= 3 (syntax-e #'x)) "x must not be 3"))) (define-syntax (foo stx) (syntax-parse stx #:context (syntax-parse stx [(_ orig-stx _ ...) #'orig-stx]) [(_ _orig-stx x:aclass ...) #''(x ...)])) (define-syntax (bar stx) (syntax-parse stx [(_ . args) #`(foo #,stx . args)])) (bar 3)


sorawee
2021-1-2 20:12:43

Here’s a quick and dirty approach


sorawee
2021-1-2 20:12:59

A better approach might be to use a syntax parameter to communicate the context


sorawee
2021-1-2 20:13:33

I have an unfinished library that does this by default


laurent.orseau
2021-1-2 20:14:09

alas I want to use foo directly also sometimes. It’s going to get dirtier :slightly_smiling_face:


laurent.orseau
2021-1-2 20:14:18

Thanks for the pointer though


laurent.orseau
2021-1-2 20:14:48

Maybe the syntax parameter idea is better. I’ve never used them


sorawee
2021-1-2 20:15:27

I notice macros that accept the original syntax are usually suffixed with /derived


sorawee
2021-1-2 20:15:39

E.g., struct/derived, for/fold/derived


sorawee
2021-1-2 20:15:47

so you can do foo/derived


sorawee
2021-1-2 20:15:59

and both foo and bar would call foo/derived


laurent.orseau
2021-1-2 20:15:59

My actual case is lambda and define


laurent.orseau
2021-1-2 20:16:22

But yeah, there could be a lambda/derived I guess


laurent.orseau
2021-1-2 20:16:30

seems messy though


laurent.orseau
2021-1-2 20:27:37

Well, my first attempt with syntax-parameters was unsuccessful, whereas the dirty approach with /derived does work and , so… thanks :smile:


spdegabrielle
2021-1-2 21:22:31

Just found this on reddit! https://youtu.be/n_7drg-R-YY


ben.knoble
2021-1-2 22:49:52

Why is it that struct? is #f when the value is a made from a struct without #:transparent and vice-versa?


jestarray
2021-1-2 22:57:58

(regexp-match #px"[[^:space:]+" bs start)


jestarray
2021-1-2 22:58:15

can anyone tell me why this isnt working ? im trying to filter out spaces and "\t" and such


soegaard2
2021-1-2 23:00:57

From: &gt; (regexp-match #px"[[^:space:]+" "foo bar baz") '("a") We can see at :space: is interpreted as the characters : s p a c e . So we need to figure out where :space: can be used.


jestarray
2021-1-2 23:02:11

so that example is only giving back “a” ? what about all the other characters?


soegaard2
2021-1-2 23:05:20

It seems the problem is that the syntax is [:space:]. &gt; (regexp-match #px"[^[:space:]]+" "foo bar baz") '("foo")


jestarray
2021-1-2 23:06:28

what if you want the rest of the characters? like bar and baz?


ben.knoble
2021-1-2 23:11:39

Quick example: (struct foo (a)) (struct? (foo 1)) (struct bar (a) #:transparent) (struct? (bar 1)) I think it might have to do with inspectors, but I don’t know what those are or why they’re relevant.


soegaard2
2021-1-2 23:14:16

Then use regexp-match*: &gt; (regexp-match* #px"[^[:space:]]+" "foo bar baz") '("foo" "bar" "baz")


jestarray
2021-1-2 23:15:05

ohhh


soegaard2
2021-1-2 23:15:06

jestarray
2021-1-2 23:16:00

one last constraint, i need to filter out backslashes and quotes


jestarray
2021-1-2 23:16:05

(#"\"H&amp;C-54-s0sc1\"")


jestarray
2021-1-2 23:16:14

\" "\


jestarray
2021-1-2 23:19:08

(regexp-match #px"[^[:space:],^[\"]+") seems to work


jestarray
2021-1-2 23:19:12

thanks for the help!


soegaard2
2021-1-2 23:23:47

This also filters out commas.


soegaard2
2021-1-2 23:24:36

Maybe: &gt; (regexp-match* #px"[^[:space:]\"\\\\]+" "foo bar,baz\\qux") '("foo" "bar,baz" "qux")


soegaard2
2021-1-3 00:22:47

One more thing to try: Use an absolute path instead of a relative one (to make sure, the proper file is read). I managed to make an example with the standard reader:

#lang racket (require racket/include) (begin-for-syntax (define (reader source-name port) (read-accept-lang #t) (read-accept-reader #t) (read-syntax source-name port))) (include/reader (file "/Users/soegaard/tmp/w1.rkt") reader) (require 'w1) x The file w1.rkt contains: #lang racket (define x 42) (provide x)


samth
2021-1-3 01:55:19

struct? means that it “struct-ness” is accessible to you, such as via reflection. Lots of things are structures that are opaque, such as channels or functions, and conceptually everything is a struct.


notjack
2021-1-3 03:07:25

maybe we ought to have named that predicate differently


samth
2021-1-3 03:38:12

Yes, the name suggests that it’s useful but it isn’t


jestarray
2021-1-3 04:37:31

cant seem to find a built in way to flatten vectors


jestarray
2021-1-3 04:37:45

i presume i turn a vector->list , flatten, then list->vector ?


me1890
2021-1-3 04:45:00

you could iterate over them with a for loop so you don’t have to construct an intermediate list


jjsimpso
2021-1-3 05:04:07

I was never able to get this to work, but I’ve moved on. I did switch to using ‘file’ to provide a full path and was able to get an example using the standard reader to work. Thanks for your help though. Much appreciated!


jestarray
2021-1-3 05:31:19

what is the extension for pure data s-expression files? e.g, ones that don’t have a #lang #( "potion" "sword" ) currently saving these as items.rkt which is fine but im wondering if there’s another name people use


jestarray
2021-1-3 05:33:40

huh, looks like there is none… welp, gonna call them .x then for now


amol.jha
2021-1-3 05:37:29

@amol.jha has joined the channel


me1890
2021-1-3 05:40:18

@jestarray does it have to have a special extension?


me1890
2021-1-3 05:40:39

you could just put .dat or something on it to denote that it’s just data


jestarray
2021-1-3 05:42:21

nah not really, at minimum i just want it to differ from the .rkt because the file manager puts a racket icon on it despite it being not really being an executable script. I’m surprised there isn’t a formally defined name for this


jaz
2021-1-3 05:42:24

.rktd



me1890
2021-1-3 05:50:21

so you just want your file manager to show it as a racket file even though it doesn’t contain racket code?


jestarray
2021-1-3 06:09:33

no, that’s what i dont want lol, anywhoo i decided on .dat like you said


me1890
2021-1-3 06:15:08

sounds good