comp.lang.ada
 help / color / mirror / Atom feed
From: jayessay <nospam@foo.com>
Subject: Re: OT: What was the first programming language to use 'generics'?...
Date: 19 Aug 2005 14:09:27 -0400
Date: 2005-08-19T14:09:27-04:00	[thread overview]
Message-ID: <m3u0hl94tk.fsf@rigel.goldenthreadtech.com> (raw)
In-Reply-To: wcc4q9m6k2y.fsf@shell01.TheWorld.com

Robert A Duff <bobduff@shell01.TheWorld.com> 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



  reply	other threads:[~2005-08-19 18:09 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-08-18  9:18 OT: What was the first programming language to use 'generics'? Martin Dowie
2005-08-18 11:29 ` Jean-Pierre Rosen
2005-08-19 16:25   ` Charles Lindsey
2005-08-18 21:11 ` David Trudgett
2005-08-18 21:36   ` Robert A Duff
2005-08-18 23:43     ` David Trudgett
2005-08-19  2:13       ` OT: What was the first programming language to use Larry Kilgallen
2005-08-19  9:44         ` David Trudgett
2005-08-19 14:22         ` jayessay
2005-08-19 15:08       ` OT: What was the first programming language to use 'generics'? Robert A Duff
2005-08-19 18:09         ` jayessay [this message]
2005-08-19 15:42     ` jayessay
2005-08-19  2:47 ` Jeffrey R. Carter
2005-08-21 17:33 ` adaworks
     [not found]   ` <odeig19vmplnbt67s3s148eb4mqrk9vujd@4ax.com>
2005-08-23  7:03     ` adaworks
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox