
(define (make-a-singleton) (struct singleton ()) (singleton))
(make-a-singleton)

This works fine - since structure definitions are “generative”, which means that each new struct declaration declares a new structure type.

Oh - misread the question. “Singleton type” not the same as a “singleton”.

@chrisjgd has joined the channel

macro expanding a struct—any thoughts on how to go about this? I went through the macro stepper and I can see it expands to say struct:foo, but I can’t seem to write a macro that does something with that

@chrisjgd can you say more about what you’re trying to do?

yep, building a lang and using structs to construct an abstract syntax tree so I can manipulate it and do things like type-checking and so forth, then I want to expand this when I’m done so it can be used as a #lang

previously I had just written a function that takes the ast and converts it into a giant s-exp that is passed to the expander after the reader takes a hold of it, but I was wondering if I can avoid that step and just expand it from the structs themselves, but maybe I’m not thinking about this right

I’m still unsure what you’re trying to do with structs

what do you mean by “macro expanding a struct”?

Ah sure, say I have a few structs, one called binop and one called num, that hold the expected things, so when I’ve parsed an expression I end up with (binop ’+ (num 1) (num 2)) as my abstract syntax tree

I want to macro expand those structs into (+ 1 2) so they can be evaluated

normally I’d just have a function that matched on the struct types and turned it into an s-exp, like (’binop ’+ (’num 1) (’num 2)) and that’s easy to macro expand to what I want

ah, it sounds like you’re wondering if there’s something you can do so you just put the the structs directly in a syntax object and have the macro expander automatically convert them to other syntax

is that right?

yep!

ok, so in general you can’t do that

there isn’t a hook for “macro expansion”

so you need to write some sort of conversion from structs to syntax objects

hmmmm, I must be misunderstanding something. If I have (struct foo ()) and then do (datum->syntax #f `(,(foo))) I get a syntax object that has (#(struct:foo)) in it

ah well, I just thought that in the context of a #lang I had some control over how things were being expanded

you can certainly do that, but expanding that just produces the same thing

and evaluating it will produce that value

which sounds like it isn’t what you want

Nope, sure isn’t. I was hoping to write a macro for struct:foo in this case, but it’s clear I have to just turn it into an s-exp so the macro expander will pick it up as expected (which I was doing anyways, I was just trying to make the whole process less error prone). Thanks for your help!

@hoshom @soegaard2 I’m not sure this is a good or useful idea, but the idea is to have a struct that contains a “spec” for the nodes and allowable edges in a graph, and a type (Graph spec)
where spec
is such a struct. Then the functions that operate on the graph could also have spec
as a type parameter, maybe something like this: (: add-edge (All (spec) (Graph spec) Port Port -> (Graph spec))

Thanks, Stephen. The problem is that the morning/afternoon streams seem to have been shot with one camera which didn’t pick up the screen contents very well. Afaict, R7 had at least two cameras and the slides were clearly visible.

@chrisjgd You might be interested in looking at the implementation of the sql
library: https://github.com/rmculpepper/sql/ It extensively uses prefab structs for an AST representation at both compile-time and run-time, and the library basically interprets the AST at run-time to emit generated SQL strings. I don’t think that’s exactly what you had in mind, but the technique might be relevant, depending on exactly what you’re ultimately doing.

Thanks @philip.mcgrath, I’ll take a look! To be honest, my first pass at a #lang just used a reader which emitted a call to an evaluate function on my AST and that totally worked (i.e., the AST was evaluated at run-time to execute the program). To learn macros I decided to convert that evaluate function into racket code with the expansion phase after the reader parses it (if what I’m saying makes sense). In any case, I’ll take a look, sounds interesting!

The web-server library that comes with racket doesn’t seem to use the racket standard library’s logging facilities. Is there any specific reason? As in, if I make my own log-and-dispatch-next dispatcher instead, any particular issues I should look out for?

I want to use racket’s logging so that I can make the server’s dispatch log be logging to a topic for which I may add multiple subscribers.