From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,3413256b2f4bedfc X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news1.google.com!news2.google.com!newsread.com!newsprint.newsread.com!news-feed01.roc.ny.frontiernet.net!nntp.frontiernet.net!newscon06.news.prodigy.com!prodigy.net!border1.nntp.dca.giganews.com!local01.nntp.dca.giganews.com!nntp.rcn.net!news.rcn.net.POSTED!not-for-mail NNTP-Posting-Date: Fri, 19 Aug 2005 13:01:55 -0500 Sender: jsa@rigel.goldenthreadtech.com Newsgroups: comp.lang.ada Subject: Re: OT: What was the first programming language to use 'generics'?... References: <43045094_1@glkas0286.greenlnk.net> From: jayessay Organization: Tangible Date: 19 Aug 2005 14:09:27 -0400 Message-ID: User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2 MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii NNTP-Posting-Host: 209.6.25.79 X-Trace: sv3-M2Duy13qAdVBMrOwJpf7Un1XqlWNw2aFh7qVysI5/znEWz1FVjOtS1NSgopruXmAoOXEmhmkqJX8iwl!q8zrhEn4Hdzoll10wMuFng2PeiAmmPm7ezx+DwG2QuUR7QXEeJxj/UTsl/mZRfiPChHjamqwTD+z X-Complaints-To: abuse@rcn.net X-DMCA-Complaints-To: abuse@rcn.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news1.google.com comp.lang.ada:4199 Date: 2005-08-19T14:09:27-04:00 List-Id: Robert A Duff writes: > I was including Lisp macros and C macros and the macros of many other > languages, including assembly languages in the term "macro systems". > Larry Kilgallen mentioned Bliss, which has an extremely powerful macro > system. Most of them, I believe, share the same problem of accidentally > referring to names visible at the place of the instantiation (macro > call). The other big one is unintended multiple evaluation of parameters. In the case of Lisp (Common Lisp), these are not a problem as David Trudgett pointed out, i.e., there are simple mechanisms available which _guarantee_ this cannot happen. OTOH, there are times when variable capture is _exactly_ what you _want_. Example (impossible unintended variable capture and no multiple evaluation): (defmacro with-foo (id &body body) (with-unique-names (gid temp) `(let* ((,gid ,id) (,temp (get-foo ,gid))) (unwind-protect (progn ,@body) (release-foo ,temp))))) gid and temp here act very similarly to "temporary variables" generated by a compiler to hold intermediate values in a generated code sequence. Both are generated at expansion time and both are universally unique. Also, a parameter passed to the formal ID will be evaluated exactly once. (defun flubber (xyz info) (let ((temp (some-computation xyz))) (with-foo (determine-foo info) (do-some-stuff temp) (setf temp (some-other-computation)) (if (some-test temp) :success :fail)))) Here's what the body of flubber expands to: (let ((temp (some-computation xyz))) (let* ((#:gid81696 (determine-foo info)) (#:temp81697 (get-foo #:gid81696))) (unwind-protect (progn (do-some-stuff temp) (setf temp (some-other-computation)) (if (some-test temp) :success :fail)) (release-foo #:temp81697)))) For this _specific_ expansion, gid and temp become "temporary variables" #:gid81696 and #:temp81697. Another expansion will generate new versions. Note that TEMP is not inadvertantly captured and the TEMP in the users code correctly refers to the outermost TEMP. > But I agree that most of them are inferior to the Lisp version > in many other respects. In this respect as well. > >... Interestingly, > > Scheme's "hygienic macros" do not make Common Lisp's macros > > "unhygienic"! They just add an extra restriction which stops the > > programmer from doing certain things that can be done in Common Lisp > > macros (from what I hear). The same level of "hygiene" can be had in > > Common Lisp macros by the use of appropriate programming style, > > including the use of GENSYM to avoid referring to extraneous "symbols" > > (read "variable names", close enough). > > This has been debated intensely in the Lisp community. My opinion > is that GENSYM doesn't make them hygienic, because GENSYM is > something you have to remember to do by hand all over the place. Not really - as you can see above. But then "hygiene" is pretty subjective. As I said above, there are times when you absolutely _want_ to have a particular variable captured. It makes the _semantics_ exactly right. In something like syntax-case, you can't do that. Which is one reason (amoung many) why all Scheme implementations actually end up providing defmacro anyway. > In Scheme macros, and Ada generics, it happens automatically. > Also, I don't see how this hygiene loses any power -- if you *want* > to capture variable names visible at the call site, you can pass > parameters to the macro/generic. That does not capture lexical variables which is what you sometimes want. /Jon -- 'j' - a n t h o n y at romeo/charley/november com