
Racket has many macros that introduce new ids (which is not hygienic), such as struct
.

this may sound really dumb and I ought to know better, but why is a macro that introduces ids non-hygenic? It seems OK to me to have a macro that expands to, say, a define
. By my lights, that’s introducing an identifier. But perhaps I’m not looking at the situation in the right way.

In the define
example the identifier is supplied by the user, and that — and only that — gets introduced.

(let ([foo-bar 42])
(struct foo (bar))
(+ foo-bar 1))

Here the struct
macro introduces a foo-bar
that shadows the one apparent in the code.

thanks, that helps

I think everyone would agree that it would be horribly tedious if you had to supply all the accessor names and the predicate when you invoke struct
.

agreed

And hopefully it’s not surprising because people know struct
.

but to my mind, all those things are still functions of the data I gave to struct; it’s as though there are lots of format-id
s being done, not just a simple define

But strictly speaking, it’s “surprising” in the way that non-hygienic macros can be surprising in bad ways.

your let
example is really illuminating

Yes, it definitely helps that the identifiers are created using a prefix that you supply.

it shows how there’s a kind of “polluting” going on by struct
that wouldn’t normally occur

I mean there are many places on the continuum of “more vs. less ceremony” or “explicit vs. implicit”, and there are always trade-offs.

As usual, the right point is, “it depends”. :smile:

I think that goes for judicious use of non-hygienic macros, too.

Also “docs” :wink: