It is, well, a very particular perspective on things, but I've heard
people speak well of it.
Shriram
_________________________________________________
For list-related administrative tasks:
http://lists.racket-lang.org/listinfo/users
It looks interesting. Very unSchemeish, though. Chapter 6, on
anaphoric macros, seems to celebrate unhygienicity.
-- hendrik
The following passage is particularly unsettling.
"Even the vast majority of Scheme systems, the platform that has
experimented the most with hygiene, provide unhygienic defmacro-style
macros—presumably because not even Scheme implementors take hygiene
very seriously. Like training wheels on a bicycle, hygiene systems are
for the most part toys that should be discarded after even a modest
level of skill has been acquired."
--Carl
The paragraph before that is a strange rant, too.
Good thing we're not Scheme anymore.
Robby
> Good thing we're not Scheme anymore.
:-) You think that guy would believe you?
I only read two paragraphs of his masterpiece so perhaps I am
misjudging him, but I'm not inclined to worry about his opinion after
that.
Maybe if he sees these messages and engages us I'll give him a read.
But I guess he doesn't much care about or for us.
Robby
If these two paragraphs are characteristic for the book, it is based on the usual misconceptions of poor Common Lispers about the world of hygienic macros, which they have never understood and are therefore afraid of.
For us, we should figure out what's good about the book and use it for our own work. We understand 'hygienic macros' and these guys' world. Advantage, us.
The author is irrelevant to us.
-- Matthias
And booleans, apparently.
> For us, we should figure out what's good about the book and use it for our own work. We understand 'hygienic macros' and these guys' world. Advantage, us.
Sounds wise.
Robby
> Having read some of the stuff, l am not impressed. Yes, in some cases we may
> want to introduce a binding not named in a macro call. Racket and R6RS
> (macro-case) do that very well. That for a beginner it is difficult to
> prepare unhegienic macros: jolly good! I have misused datum->syntax a couple
> of times, just to find out later that I did not need it realy (although I
> recognize that in some cases it may be usefull)
> Jos
My experiences are similar. On the few occasions that I have used unhymacs, I first wrote and debugged hymacs; this path allows macro novices like myself to see and justify (or not) the need for developing them into unhymacs. To me, good development environments provide 'complication stages' that can be clearly understood and encountered only when required.
rac
I continue to be delighted when I find that syntax-rules often
provides an easily understood and syntactically pleasant solution to
problems that I thought could only be solved by syntax-case and
functions. Of course the problem lies within myself, not syntax-case!
I've ran into this book a while ago -- it's just an overall bad piece
of text, not just the macro parts. (And not even counting his hygiene
ignorance (which is overall very popular in the CL world, usually a
by-product of equating "hygiene" with `syntax-rules').)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
Anaphoric macros are deliberately unhygienic. But I didn't get the
impression that all or even most of the macro techniques were
unhygienic. Am I wrong and didn't get deep enough into the books? To
put it another way, is the negative reaction here due to him dissing
hygiene, or is it reflective of a deeper and broader disagreement with
the entire approach of putting macros on a pedestal?
BTW I'm asking this innocently, genuinely not knowing the answer,
curious what more experienced people think.
Anyways, to your actual question: my answer would be that most macros
I know are hygenic. Ie, if you have to pick a default for variables
introduced by a macro, hygenic is the right one.
Robby
> But I didn't get the
> impression that all or even most of the macro techniques were
> unhygienic.
Hygiene is a technical term. The idea is roughly that
the __macro system__ (as a whole) should respect the
lexical structure of your program. That is, by default
no programmer should be able to accidentally write a
macro that messes up lexical bindings in a subtle way.
Roughly speaking, macro hygiene is like safety. The latter
also is a property of the language, meaning all programs
have it, no matter the skill of the programmer who uses
them. In particular, it doesn't make much sense to say
an individual macro is hygienic or that an individual
program is safe. You can 'prove' certain fail-safety
properties about each but that's all. The word 'prove'
is meant in the general sense that reasoning about
programs constitutes an attempt to make sure it is always
exhibiting the desired properties, no matter the context,
input, or whatever.
(When I coined the phrase 'hygienic macro' I was reading
a paper by Barendregt who used it in a similar context
for dismissing detail concerns about substitution in LC.
(My coauthors loved the term and so we took it. Another
candidate had been 'synthetic' or something like that.))
-- Matthias
Once you understand that, you realize that it is simply not meaningful
to say that a *macro* is "hygienic" -- that phrase is not even wrong.
Shriram
Robby
Not necessarily -- see syntax parameters. The idea is that there is
an identifier (like `it') which is managed like all other identifers,
and it has some use only inside some lexical context (like the
consequence branches of an `if').
> [...] To put it another way, is the negative reaction here due to
> him dissing hygiene, or is it reflective of a deeper and broader
> disagreement with the entire approach of putting macros on a
> pedestal?
In my case, my negative reaction is to CLers who think that hygiene is
somehow equivalent to `syntax-rules', and because `syntax-rules' has
the limitations that it does, they conclude that hygiene as a whole is
an academic toy. One that you dump when you get to write Real Code.
20 minutes ago, Matthias Felleisen wrote:
>
> On Nov 20, 2010, at 9:01 PM, Greg Hendershott wrote:
>
> > But I didn't get the impression that all or even most of the macro
> > techniques were unhygienic.
>
> Hygiene is a technical term. [...]
BTW, there's a good number of CLers that object to the actual term,
since they see it as something that implies that their macros are
"dirty".
> (When I coined the phrase 'hygienic macro' I was reading
> a paper by Barendregt who used it in a similar context
> for dismissing detail concerns about substitution in LC.
> (My coauthors loved the term and so we took it. Another
> candidate had been 'synthetic' or something like that.))
[IMO, a good term would be one that makes CL macros be "symbolic" or
"concrete" -- something that indicates that the good macros are ones
where you don't usually care about the actual characters that make up
an identifier in code that you write...]
40 minutes ago, Robby Findler wrote:
> (like the paragraph that complained about booleans in Scheme; it
> didn't make much sense to me).
I think that it is just a confused criticism -- he *probably* intended
to praise the CL property that false is the same as the empty list,
and that many core functions (like `car' and `cdr') return nil when
given it instead of throwing an error. If this is wrong, then he
knows so little about scheme that he should never have mentioned it.
If it's true, then it indicates bad sloppiness on his part -- the kind
that exposes biased opinion.
10 minutes ago, Shriram Krishnamurthi wrote:
> In particular, something many people miss -- because of the way
> hygiene is presented -- is that a hygienic macro system must have a
> deep understanding of the underlying language, at least up to the
> level of the binding structure of its constructs. That is how it
> can even be sure what is a binding, where it is bound, and thus what
> can be painted/renamed/closed over/tweaked/whatever.
+1. I like to say that CL macros make a huge jump from CPP or M4:
from unstructured text to structural "pre-parse" trees. And due to
what Shriram says, hygienic macros make an equally huge jump to having
information about the binding structre (more or less) of the code.
(And in this context "hygienic macros" really mean all
hygiene-breaking `syntax-case'-style macros -- since the information
was there even if some macro chose to inject a concrete name.)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
>
> On Nov 20, 2010, at 9:01 PM, Greg Hendershott wrote:
>
>> But I didn't get the
>> impression that all or even most of the macro techniques were
>> unhygienic.
>
>
> Hygiene is a technical term. The idea is roughly that
> the __macro system__ (as a whole) should respect the
> lexical structure of your program. That is, by default
> no programmer should be able to accidentally write a
> macro that messes up lexical bindings in a subtle way.
Dave Herman mentioned this to me some time ago, and my immediate response was this: okay, if the term "hygiene" refers to a macro system and not to a macro, then *what word* should we use to describe macros that violate transparency? "non-transparent"?
John
Oh dear... would that word be "anaphoric"?
John
I don't want to take any sides in this debate -- which seems to
drift into a "Scheme vs Common Lisp" debate -- I just want to point to
the "Clarifications" page written by the same book author regarding
it's controversies:
http://letoverlambda.com/index.cl/clarifications
Ciprian.
P.S.: It just happens that a few weeks ago I've started reading
the book online, and from yesterday I also have the book. And I kind
of like the macro stuff described in there. (And just for the record I
prefer Scheme over Common Lisp.)
Moreover, the macros described in his book (by using a certain
methodology) are not that different from a primitive hygienic-like
macro system. For example he defines the `square` macro as:
http://letoverlambda.com/index.cl/guest/chap3.html#sec_6
~~~~
(defmacro! square (o!x)
`(* ,g!x ,g!x))
~~~~
(defmacro! square (o!x)
`(progn
(format t "[~a gave ~a]~%"
',o!x ,g!x)
(* ,g!x ,g!x)))
~~~~
So my personal opinion (as an amateur Lisp-ish programmer) is that
if someone is interested in DSL's he could read the book, at least to
get an idea of what can be achieved in a Lisp-ish environment. (I
actually want to understand his ideas and techniques and try to see
how to better adapt and apply them to Racket in the context of
hygienic macros (I currently only know `syntax-rules` so maybe the
next step is to understand "hygienic" macros, thus any good pointers
are welcomed).)
Robby
> Dave Herman mentioned this to me some time ago, and my immediate response was this: okay, if the term "hygiene" refers to a macro system and not to a macro, then *what word* should we use to describe macros that violate transparency? "non-transparent"?
>
How about opaque?
- --
Eduardo Bellani
omnia mutantur, nihil interit.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/
iEYEARECAAYFAkzsOGUACgkQSbLl0kCTjGldJQCfXKyiwWpBrJNSkReM18CJsYZD
/18An0Xz9leioka2wuPQgYnDK4yA3JUK
=H+y4
-----END PGP SIGNATURE-----
A macro that violates hygiene.. 'violator'
Some Scheme systems have theoretically advanced macro systems but I
believe the Common Lisp macro system is more suitable for writing
useful macros.
Eh? How about a huge chunk of the cool things in Racket, from the
class system to Typed Racket to Lazy Racket to FrTime?
He does not understand that a macro system that closes over bindings
from other modules is a *fundamentally different thing* than a mere
macro system. It is hard to overstate this matter; it is foundational
to what makes Racket a different language than Lisp or Scheme.
In fact, this merely demonstrates that where macros are concerned,
he's a Blub programmer. (He may indeed be in the top-10%ile of
Blubberers.)
I'm aware that he says
If you disagree and have examples to back up your opinions, I'd love
to hear from you.
but perhaps if he were truly interested in learning, *he* would
contact the authors of those "theoretically advanced systems" and ask
them to educate him, not put the burden on them.
Shriram
PS: This message is public, so anyone who wants to is welcome to
forward it to him or anyone else, w/out asking me for permission.
His response makes perfect sense. We don't have a a "theoretically
advanced macro system", we have a "practically advanced macro system".
Also, that is a part of Racket, not part of our support for Scheme.
All it says is that he needs to learn about Racket.
> He does not understand that a macro system that closes over bindings
> from other modules is a *fundamentally different thing* than a mere
> macro system. It is hard to overstate this matter; it is foundational
> to what makes Racket a different language than Lisp or Scheme.
>
> In fact, this merely demonstrates that where macros are concerned,
> he's a Blub programmer. (He may indeed be in the top-10%ile of
> Blubberers.)
>
> I'm aware that he says
>
> If you disagree and have examples to back up your opinions, I'd love
> to hear from you.
>
> but perhaps if he were truly interested in learning, *he* would
> contact the authors of those "theoretically advanced systems" and ask
> them to educate him, not put the burden on them.
It seems like little work to send him a link to Racket.
Robby
It's more than that -- the "theoretically advanced ... but" that he
uses shows off that he really considers the CL macros to be more
advanced. And given that implementing the CL system is much easier
(and requires less code), my conclusion is that:
> If you disagree and have examples to back up your opinions, I'd
> love to hear from you.
is a vacuous request that can only result in flames.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
Now good luck trying to define what that category is! I worked on that problem for nigh onto 8 years, and all I have to show for it is a dissertation.
Dave
No, maybe I wasn't clear. It's hard to come up with a precise definition of the class of macros that John's talking about. When Matthias et al invented hygienic macro systems, the idea was that the system would "get scope right" (an intentionally vague phrase) by having the right defaults. But it's all defined at the level of mechanism; no one's ever been able to identify actual guarantees provided by hygienic macro systems.
In my work, I identified a restricted model where you *could* give precise definitions to these things, but that model was not the same as Scheme/Racket. It purposefully left out problematic programs.
> Racket allows for unhygienic macros
What this whole thread has been about is that "unhygienic macros" is a nonsense phrase.
> so does Racket not implement a "hygienic macro system"?
Racket is hygienic in that it has mechanisms to make scope work out "the way you want" most of the time by default. That you can override the defaults and write macros that do funky things does not make it unhygienic. Notice that I say "that do funky things" and *not* "that are unhygienic" because, again, the idea of an unhygienic macro is just pretty ill-defined in Scheme. The technique of "Petrofsky abstraction," while it doesn't demonstrate exactly what Al Petrofsky claims it does, actually demonstrates the principle that the intuition usually given (an "unhygienic macro" is one that captures an identifier that "didn't come from its input") is flawed.
Regardless, whether or not you can come up with a quasi-precise notion of what such macros that John's asking for a name for, the question of terminology is historical, not mathematical. And Matthias coined the term with the idea that a hygienic macro system is one that has the right defaults for scoping, regardless of whether you can break out of the defaults. Which means Racket is no less hygienic than a system with just `syntax-rules'.
Dave
I doubt it. "Anaphoric" already has a very specific meaning in this
kind of context.
A traditional riddle among linguists is this:
Q: What's the difference between a dead sheep and a dead sheep?
A: Anaphoric blocking
Anaphoric blocking refers to the rule that an identically repeated
indefinite noun phrase never refers to the same thing both times.
So methinks anaphoric may not be the right word here.
-- hendrik
>> Is this like the difference between C's type system and ML's?
>
> No, maybe I wasn't clear. It's hard to come up with a precise definition of the class of macros that John's talking about. When Matthias et al invented hygienic macro systems, the idea was that the system would "get scope right" (an intentionally vague phrase) by having the right defaults. But it's all defined at the level of mechanism; no one's ever been able to identify actual guarantees provided by hygienic macro systems.
Right! So we have a word--"hygienic"--which we can use to describe a set of macro systems, even though we can't precisely define which macro systems those are. I'm asking for another, different, word to use for those macros that would formerly have been described as "unhygienic"; for instance, the macro which wraps an expression 'M' in the context (let ([x 5]) []). I realize that this word wouldn't currently have a precise definition, but then, as you've pointed out, neither does "hygienic."
John
That's because he apparently only knows about syntax-rule and not
syntax-case. Look for the word "hygienic" in chapter 3 of his book:
http://letoverlambda.com/index.cl/guest/chap3.html
"It is no wonder that the Scheme designers have experimented with
so-called hygienic macro systems to avoid having to type gensym all
over the place. The wrong turn that Scheme took was to promote a
domain specific language for the purpose of macro construction. While
Scheme's mini-language is undeniably powerful, it misses the entire
point of macros: macros are great because they are written in lisp,
not some dumbed down pre-processor language."
(See also http://lists.ccs.neu.edu/pipermail/prl/2009q3/002307.html
this discussion already happened a year ago on another public mailing
list not far from this one)
Philippe
Yeah, I said earlier that it's "hygiene ignorance (which is overall
very popular in the CL world, usually a by-product of equating
"hygiene" with `syntax-rules')". The bottom line is if you mail him
(or maybe post on c.l.l) you won't get far: you can claim that you can
do any macro that he can and do so, but once he (or any average cller)
sees `syntax-case' you'll get flamed because *obviously* he was
talking about "standard scheme", and *obviously* he rightfully doesn't
know or care about whatever insignificant local extensions racket made
on top of that.
A new piece in such games is the fact that R6RS *does* have
`syntax-case' etc, and -- unsurprisingly -- that doesn't help either.
(You'll get flamed because it's controversial, or because it was
published after the book came out, or maybe I can just put you on hold
for a minute because I have something in the oven.)
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
"Debugging programs is harder than writing programs. Those who write programs at the limits of their ability are unqualified to debug them."
In this case: "Macros are harder to understand than fundamental programming. Those who use macros at the limits of their ability are unqualified to talk about them."
So, why are new words needed?
rac
In this case
Nevermind let/lambda, when is the programming in *Racket* book coming?
All good PL's have a book don't they?
It's not a perfect match. Single-word anaphor (like "it") wouldn't
normally be called noncompositional because there's nothing to compose
there---the word just has a complex meaning. And in natural language
there's no analogue at all to the more complex things that macros can
do. But to the extent that a hygienic macro system tries to make it
difficult (or impossible) to write macros that capture values, and a lot
of people informally use the term "unhygienic macro" to refer to "macros
that hygienic macro systems try to prevent", the core thing that's being
prevented is essentially noncompositionality.
To turn it around, if I hand you a compositional expression, I also hand
you the syntax rule and the values of all evaluable sub-expressions,
then you can 100% reliably hand back the value of the overall
expression, and this seems to be the core desideratum when people start
talking about hygienic macro system.
--
-=-Don Blaheta-=-dbl...@monm.edu-=-=-<http://www.monmsci.net/~dblaheta/>-=-
"The "melting pot" theory works in some areas in the larger cities. The
"salad bowl" theory works rather well for other towns and cities. But I
propose a third theory that covers vast areas of the US. The "child's plate"
theory. In this theory all of the foods are separated into their own groups
and if the ketchup touches the green beans all hell breaks loose."
--Brian Pyle
> These two threads remind me of an observation that I wish I could cite:
>
> "Debugging programs is harder than writing programs. Those who write
> programs at the limits of their ability are unqualified to debug
> them."
You might be thinking of this:
"Debugging is twice as hard as writing the code in the first
place. Therefore, if you write the code as cleverly as possible, you
are, by definition, not smart enough to debug it." (Brian W. Kernighan
and P. J. Plauger in The Elements of Programming Style.) [1]
[1] http://quotes.cat-v.org/programming
Best,
Richard
It is somewhat unfortunate that the name `hygiene' has caught
on here. It really ought to be called `lexical scoping' (with the
understanding that macros have no special permission to violate
lexical scope any more than lambda bindings do).
On Tue, Nov 23, 2010 at 11:08 AM, John Clements
<clem...@brinckerhoff.org> wrote:
>
> then *what word* should we use to describe macros that violate transparency? "non-transparent"?
I've seen `non-hygienic'. I'd vote for `broken'.
--
~jrm
I've always hated this quote. Debugging is simply not that hard, nor is
complexity that unmanageable. This isn't to say that *needless* complexity
is fine, just that we all write code that is beyond our ability to completely
understand (or we wouldn't have bugs in the first place!).
--
~jrm
You know about Oleg's macro called, bind-x-to-5 that has one
subexpression does exactly its name claims, but in a hygenic macro
system?
That example suggests to me that what is called hygiene should
probably not be called lexical scope.
Robby
Yes. And I have to admit that I've used this trick myself to write
some questionable (but useful) macros.
> That example suggests to me that what is called hygiene should
> probably not be called lexical scope.
I'm not sure. Certainly the r5rs hygienic macro system has the
ability to mimic non hygienic use.
But consider these statements:
`Any sufficiently powerful macro system can appear to break
lexical scope.'
`Any macro system weak enough to preserve lexical scope is
too weak to do X' (where X is something one would normally
expect to be able to do with a macro)
I have not seen a claim or proof of either of these or a denial
of either. In other words, perhaps there is a macro system that
is both sufficiently powerful and general that we'd all agree it
qualifies as a macro system, yet is weak enough that we all agree
it cannot violate what we consider `lexical scope'.
Alternatively, perhaps one could argue that our understanding of
`lexical scope' is too narrow and primitive, and that Oleg's
bind-x-to-5 macro is simply a surprising, but consequential artifact
of the true meaning of `lexical scope'.
I rather prefer the former alternative. The current macro system is
an amazing piece of insight and engineering, but it does have a few
dark corners: Oleg's bind-x-to-5 is one, accidental export of internal
bindings is another.
--
~jrm
I consider Oleg's example (which doesn't use datum->syntax or anything
fancy like that) to be an example to substantiate the first sentence
above.
> Alternatively, perhaps one could argue that our understanding of
> `lexical scope' is too narrow and primitive, and that Oleg's
> bind-x-to-5 macro is simply a surprising, but consequential artifact
> of the true meaning of `lexical scope'.
That might be true but I don't like it either.
> I rather prefer the former alternative. The current macro system is
> an amazing piece of insight and engineering, but it does have a few
> dark corners: Oleg's bind-x-to-5 is one, accidental export of internal
> bindings is another.
IMO, the macro system is good, but the phrase "lexical scope" is bad
and we should find another one that is more accurate and helps get at
the essence of why we consider the macro system good.
Dave Herman may have an opinion here. :)
Robby
Hang on... you're still using the term "hygienic" in the non-Felleisen way. That is, if we accept that a hygienic system is one that has well-defined behavior but where you can bind new names when you explicitly ask to, then
#lang racket
(define-syntax (bind-x-to-5 stx)
(syntax-case stx ()
[(_ exp)
#`(let ([#,(datum->syntax stx 'x) 5])
exp)]))
(bind-x-to-5 x)
...is a legal macro in a hygienic macro system.
Right?
John
No I'm not.
> That is, if we accept that a hygienic system is one that has well-defined behavior but where you can bind new names when you explicitly ask to, then
>
> #lang racket
>
> (define-syntax (bind-x-to-5 stx)
> (syntax-case stx ()
> [(_ exp)
> #`(let ([#,(datum->syntax stx 'x) 5])
> exp)]))
>
> (bind-x-to-5 x)
>
> ...is a legal macro in a hygienic macro system.
Sure.
But Oleg's macro doesn't do that.
Robby
>
> Hang on... you're still using the term "hygienic" in the non-Felleisen way. That is, if we accept that a hygienic system is one that has well-defined behavior but where you can bind new names when you explicitly ask to, then
That's too loose a definition. The Common Lisp macro system has
well-defined behavior,
and you can bind new names when you explicitly ask, yet it is not hygienic.
I expect that Kohlbecker has a reasonable definition (but I'm too lazy
to look it up right now),
but I'd say that `hygiene' at the very least involves a default
behavior of preserving
the lexical scope at the point of macro use. I'd say that having the
ability to inject new
bindings or shadow existing ones is perhaps an `advanced feature' that
may be desirable,
but not necessary. (Frankly, I'm very opposed to injecting any sort
of binding or name
that does not appear as a literal identifier near the point of use,
but I don't really care if
other people want to write bad code.)
It is the default behavior that is of interest. It allows me to
understand code fragments
such as:
(let ((x 22))
(frob x)
x)
and to *know* that alpha-renaming `x' does not involve looking at the
expansion of `frob'.
$0.02 my current personal view is that the books, and other forms of
'getting the word out', would be better.
sincerely.
That's sort of what I was trying to get at, but I don't think that definition is
strict enough. That's why I phrased it in terms of alpha-renaming. Basically,
you should be able to alpha-rename the identifiers you introduce in
your own code
without fear of name collision from a macro, and the macro writer should be able
to do the same.
--
~jrm
You are right, but I bet you couldn't get a librarian or bookseller to
find you a book on Racket.
Of course there is already a book in the within the guide sections of
the Racket documentation that is at least as good as 'dive into
python'.
S.
> Stephen De Gabrielle wrote at 11/24/2010 11:43 AM:
> Nevermind let/lambda, when is the programming in
> *Racket* book coming?
>
> All good PL's have a book don't they?
>
>
>
> --
> http://www.neilvandyke.org/
>
>
>
>
--
--
Stephen De Gabrielle
stephen.d...@acm.org
Telephone +44 (0)20 85670911
Mobile +44 (0)79 85189045
http://www.degabrielle.name/stephen