guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Making apostrophe, backtick, etc. hygienic?


From: Panicz Maciej Godek
Subject: Re: Making apostrophe, backtick, etc. hygienic?
Date: Sun, 30 Aug 2015 15:57:54 +0200

2015-08-30 15:16 GMT+02:00 Taylan Ulrich Bayırlı/Kammer <address@hidden>:
Panicz Maciej Godek <address@hidden> writes:

> You mean that #'x is synonymous to (syntax x), and that's where the
> problem stems from?

Yup.  I shadow 'syntax', but I don't explicitly shadow "#'".  It gets
shadowed implicitly.  Lexical scoping and hygiene are supposed to let
the programmer forget about such worries.

> I think that every lisper should know that 'x is synonymous to (quote
> x), and in some contexts it might be desirable to bind a new meaning
> to the "quote" form (and this is already done by some libraries,
> notably in the (ice-9 match) module).

One may know, but still forget when sufficiently tired, and/or when
using the word "quote" to mean something conceptually different than the
quoting in lisp.

You could say that about practically any keyword in Scheme, or for that matter any other language. The advantage of Scheme is that it really allows you to redefine any keyword you like. Your point is that quote (and unquote, and quasiquote, and syntax, and unsyntax, and quasisyntax) is a reader macro, so one might forget that 'x is really (quote x) -- because that indeed cannot be infered from the source code.
 
For instance, some kind of text processing program might give the term
"quote" a specific meaning in the program's problem domain, and once
you're immersed deeply enough in this domain, you might find yourself
naming some function parameter "quote" without giving it a second
thought.  Kind of difficult to explain what I mean, but I know it
happens to me when I'm not careful.

You've got the point, but I think that the only reasonable solution would be to make the compiler issue warning whenever reader macro identifiers are being shadowed.
 
  As another example, it also keeps
happening to me that I write code like:

    (syntax-rules ()
      ((_ foo)
       (begin
         ...
         (let ((foo bar))
           ...))))

where I forget that the 'foo' there will not be bound freshly by that
let form, and that despite that I understand how 'syntax-rules' works
very well (externally, not necessarily internally!).  One is just
accustomed to be able to let-bind whatever one wants, and lexical
scoping and hygiene take care of all worries ... except when not. :-)
(In this case it has nothing to do with quote/syntax/etc., just giving
an example of what silly mistakes I can make when not careful.)


Well, misspellings happen all the time, but I think that just as their consequences can usually be avoided in real life by use of sanity, unit-testing your code is the best way to make sure that it is sane.
 
(Nowadays I name all my pattern variables <foo> for that reason.  Reads
like BNF too, which is nice.  And I don't see it ever clashing with
record type names in practice.)

> As to "syntax", the use of #'x is much rarer, and the idea that #'x is
> (syntax x) is indeed a bit controversial. But this regards the whole
> syntax-case macro system, and I think that it would be more valuable
> to think how to fix its flaws, rather than change the very
> fundamentals of the language.

Hmm, I'm not sure what flaws of syntax-case you have in mind.  IMO it's
a pretty nice system.

syntax-rules are nice, because they allow to comprehend macro transformations in terms of textual substitutions (as it is the case with functional programming), but because they expand in normal (rather than applicative) order, it's difficult to write more complex macros.
The well-known solution is to use CPS macros (which are very difficult to comprehend) or Oleg Kiselyov's idea to implement the CK abstract machine in them.
The third way, often the most intuitive, to influence the order of expansion, is to use syntax-case. However, if you do so, you can no longer (in general) analyze the macros in terms of textual substitution. And you need to use some new weird special forms, like the aforementioned "syntax"

But either way, I don't think making #'foo expand
to (__syntax__ foo), and simply making __syntax__ a synonyms to syntax,
are fundamental changes. 

Putting the issue with "syntax" aside, making 'foo expand to (__quote__ foo) would be surprising to anyone who actually wanted to shadow "quote". As I mentioned earlier, there are libraries that make use of the fact that 'x is (quote x). Take a look in here, for example:
http://git.savannah.gnu.org/gitweb/?p=guile.git;a=blob;f=module/ice-9/match.upstream.scm;h=ede1d43c9ff8b085cb5709678c4227f5ecaaa8a5;hb=HEAD#l335

(match '(a b)
  (('a 'b) #t)
  (_ #f))

would no longer evaluate to #t, because the ('a 'b) pattern would actually be read as ((__quote__ a) (__quote__ b)). You'd need to change all occurences of "quote" with "__quote__" in the match.upstream.scm (and in every other library that shadows quote for its purpose) in order to make it work, thus making Guile non-RnRS-compliant.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]