From: ······@exploited.barmy.army
Subject: Overwriting Functions/Macros?
Date: 
Message-ID: <6frjfr$bds$1@Masala.CC.UH.EDU>
Hi all,

I would like to reimplement a built in macro and have my new 
implementation call the old one.  For example, given macro x
I would like to do something like:

(defmacro x
	`(... call-old-x ...))

I tried storing the original macro in a variable (setq v #'macro-name),
but then I could not find out how to call it (a macro equivalent to
funcall?).  Also, I'm not sure if (setq v #'macro-name) is guaranteed 
to work on all implementations.

So what would be the best way of accomplishing this, if it is possible?

I looked through Cltl2, but could find nothing.

Also, while I did manage to get this to work with functions I am
also suspicious of my implementation.  I did:

(setq f #'function-name)

(defun function-name (...)
	(... 
	(funcall f ...)))

The problem is I don't know if this is standard behavior.  Is this
a good idea, or is there a better way?

IN particular, what has me worried is the prospect of having
f point to an address with function-name in memory that is overwritten by
the new definition.

Thanks in advance for any assistance offered.


-- 
Ahmed

To respond via email, send email to punkrock at cs dot uh dot edu

From: Erik Naggum
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <3100365962143706@naggum.no>
* ······@exploited.barmy.army
| Hi all,
| 
| I would like to reimplement a built in macro and have my new 
| implementation call the old one.  For example, given macro x
| I would like to do something like:
| 
| (defmacro x
| 	`(... call-old-x ...))

(defmacro wanker::x
  ... (whatever:x ...) ...)

  in other words, use the package system, shadow the symbol whose meaning
  you want to change, and be explicit about the package of the original.

  or use advice, if your implementation offers them.

#:Erik
-- 
  religious cult update in light of new scientific discoveries:
  "when we cannot go to the comet, the comet must come to us."
From: Barry Margolin
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <GBjU.32$XC.713938@cam-news-reader1.bbnplanet.com>
In article <············@Masala.CC.UH.EDU>,
 <······@exploited.barmy.army> wrote:
>I tried storing the original macro in a variable (setq v #'macro-name),
>but then I could not find out how to call it (a macro equivalent to
>funcall?).  Also, I'm not sure if (setq v #'macro-name) is guaranteed 
>to work on all implementations.

It isn't.  I think you want:

(setq v (macro-function 'macro-name))

To call it, you use (funcall v <form> <env>).  <env> should be the
&environment parameter to the macro.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
From: Marco Antoniotti
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <lw67kuvvyf.fsf@galvani.parades.rm.cnr.it>
Barry Margolin <······@bbnplanet.com> writes:

> In article <············@Masala.CC.UH.EDU>,
>  <······@exploited.barmy.army> wrote:
> >I tried storing the original macro in a variable (setq v #'macro-name),
> >but then I could not find out how to call it (a macro equivalent to
> >funcall?).  Also, I'm not sure if (setq v #'macro-name) is guaranteed 
> >to work on all implementations.
> 
> It isn't.  I think you want:
> 
> (setq v (macro-function 'macro-name))
> 
> To call it, you use (funcall v <form> <env>).  <env> should be the
> &environment parameter to the macro.

Which, IIANM, can be portably set only to NIL.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Kent M Pitman
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <sfwlntqdj7o.fsf@world.std.com>
······@exploited.barmy.army writes:

> I would like to reimplement a built in macro and have my new 
> implementation call the old one.  For example, given macro x
> I would like to do something like:
> 
> (defmacro x
> 	`(... call-old-x ...))

I recommend the following approach which is clean and is really the intended thing.
(I did not however -test- this code, because it was inconvenient to do so at the time
I was writing this message.  Caveat emptor, or however that goes...)

;;; Redefine DOTIMES to permit RETURN but not GO.

(defpackage "MY-EXTENSIONS"
  (:use "COMMON-LISP")
  (:shadow "DOTIMES")
  (:export "DOTIMES"))

(in-package "MY-EXTENSIONS")

(defmacro dotimes ((var initform &rest maybe-resultform) &rest body)
  (let ((decls '())))
    (loop (unless (and body (consp (car body)) (eq (caar body) 'declare))
	    (return))
          (push (pop body) decls))
    (setq decls (nreverse decls))
    `(common-lisp:dotimes (,var ,initform ,@maybe-resultform)
       ,@decls
       (progn ;mask the implicit tagbody supplied by cl:dotimes
         ,@body)))

(defpackage "FOO"
  (:use "COMMON-LISP" "MY-EXTENSIONS")
  (:shadowing-import-from "MY-EXTENSIONS" "DOTIMES") ;avoid symbol conflict
                ; since both CL and MY-EXTENSIONS export DOTIMES
);egakcapfed

(in-package "FOO")

(defun foo5 ()
  (dotimes (i 5)
    i ; ignored   <-- relies on FOO::DOTIMES making this a variable, not a go tag
    (print 'foo)))


- - - - - 

The point is that if you using shadowing, you can produce equivalent packages
of code without actually "redefining" system macros.  The old one has a name
and the new one has a name, and everyone who wants either of them can conveniently
access the one they want without clashing.
From: Marco Antoniotti
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <lw4t0dwkc7.fsf@galvani.parades.rm.cnr.it>
Kent M Pitman <······@world.std.com> writes:

> 
> (defpackage "MY-EXTENSIONS"
>   (:use "COMMON-LISP")
>   (:shadow "DOTIMES")
>   (:export "DOTIMES"))
> 
> (in-package "MY-EXTENSIONS")
> 

As an aside, I see also that using strings in package related
functions and macros for package names and symbol names is a *good*
thing.

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Erik Naggum
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <3100440858017572@naggum.no>
* Marco Antoniotti
| As an aside, I see also that using strings in package related functions
| and macros for package names and symbol names is a *good* thing.

  uhm?  why?  using strings interferes with case massaging in the Lisp
  reader.  the only advantage is that no new symbols are created, but using
  uninterned symbols or keywords (for package names) isn't _that_ much
  trouble, is it?

#:Erik
-- 
  religious cult update in light of new scientific discoveries:
  "when we cannot go to the comet, the comet must come to us."
From: Kent M Pitman
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <sfw1zvghh8w.fsf@world.std.com>
Erik Naggum <······@naggum.no> writes:

> * Marco Antoniotti
> | As an aside, I see also that using strings in package related functions
> | and macros for package names and symbol names is a *good* thing.
> 
>   uhm?  why?  using strings interferes with case massaging in the Lisp
>   reader.  the only advantage is that no new symbols are created, but using
>   uninterned symbols or keywords (for package names) isn't _that_ much
>   trouble, is it?

Marco is right, IMO.  Because of introspective operations (like INTERN,
DO-SYMBOLS, etc.) programs can detect a symbol and therefore can be affected
by a symbol which they do not directly refer to.  This is a serious barrier
to a GC trying to dump out a trim application.  When you name symbols in a
DEFPACKAGE with symbol names, you intern them, and then later it's hard to 
guess why they were interned--was it only for a momentary help in changing
the case the user was too lazy to change, or for some material reason?
Often a Lisp system contains a tree-shaker option that says to just remove
such symbols blindly, but such a heuristic is nothing more than a heuristic
and is, IMO, bad style to use.  Consequently, better not to make the garbage
in the first place.

It is a religious matter at some level, since some just don't care if
that stuff gets GC'd and some don't mind telling the system to blindly
GC.  Perhaps it's just too small an issue to care about.  But the side
of Empirically Observable Right is technically on my side on this one,
I think, Erik.

Actually, an area I've started to recently feel worse about is the use
of keyword symbols as slot initargs, etc.  When one does:

 (defclass foo () 
   ((width :initarg :width :accessor width)))

I'm starting to feel like we're building up a LOT of symbols like :WIDTH
here that are utterly gratuitous, all so we can say
  (make-instance 'foo :width 3)
instead of
  (make-instance 'foo 'width 3)
ok, and admittedly sometimes
  (make-instance 'fred:foo 'fred:width 3)
or even
  (make-instance 'fred:foo 'bill:width 3)
if it's an inherited symbol that is not re-exported (which would be
unusual, I think).  But the fact is that we deliberately go out of our
way to (a) create a possible package collision and (b) almost double the
number of symbols in the class system (if you assume the number of named
slots far exceeds the number of named classes and so dwarfs other quantities).

Then again, one of the things that has traditionally been a Lisp strength
is that one just learns not to care about such small issues, not because
they don't add up, but because they only ever amount to constant factors.
And it is the willingness to disregard constant factors in the result that
gives Lisp its never-tabulated but still-believed-large leg up in speed of
appliction development over some other languages, keeping the programmer
focused on the domain problem and not the implementation details, which
can drive any programmer mad.

So just ignore me.
From: Marco Antoniotti
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <lw3efwwqyb.fsf@galvani.parades.rm.cnr.it>
Erik Naggum <······@naggum.no> writes:

> * Marco Antoniotti
> | As an aside, I see also that using strings in package related functions
> | and macros for package names and symbol names is a *good* thing.
> 
>   uhm?  why?  using strings interferes with case massaging in the Lisp
>   reader.  the only advantage is that no new symbols are created, but using
>   uninterned symbols or keywords (for package names) isn't _that_ much
>   trouble, is it?

I do not remember what the HyperSpec says about case massaging,
however, CLtL[12] kind of assumes that symbol names are always
converted to uppercase.

It is not that much more trouble to use uninterned symbols or keywords
for package names and listed symbols.

It is just a matter of style and of saving symbols.


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 80 79 23, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Tim Bradshaw
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <ey3emzgtw75.fsf@gairsay.aiai.ed.ac.uk>
* Erik Naggum wrote:
>   uhm?  why?  using strings interferes with case massaging in the Lisp
>   reader.  the only advantage is that no new symbols are created, but using
>   uninterned symbols or keywords (for package names) isn't _that_ much
>   trouble, is it?

Well if you *don't* use strings or uninterned symbols then you're
likely to lose horribly at some point because you may not know enough
about the state of the package system (in particular what the current
package is when you define a package) to avoid interning symbols at
read time in packages in which it not be a good thing to intern them
(especially for things you're exporting from the package being
defined).

(The case that caused me to start using strings was where I had a
package definition which did (:export a b c ...), where I wanted later
to use that package from CL-USER.)

I suppose you could religiously use uninterned symbols (or keywords
perhaps) but that always looks pretty grotesque to me...

--tim
From: Espen Vestre
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <w6sonwee7g.fsf@gromit.nextel.no>
Tim Bradshaw <···@aiai.ed.ac.uk> writes:

> I suppose you could religiously use uninterned symbols (or keywords
> perhaps) but that always looks pretty grotesque to me...

I always use keywords - probably because they look _prettier_ to me!

--

  espen
From: Steven D. Majewski
Subject: strings, symbols or keywords (was: Overwriting Functions/Macros?)
Date: 
Message-ID: <6g0j00$8hq$1@murdoch.acc.Virginia.EDU>
Glad to see this topic come up --
I thought I was the only one to worry about this. 

I used strings until I ran into some problems with case consistency
with REQUIRE, PROVIDE and how they were stored in *modules*. 

Then, I switched to using symbols, so I didn't have to worry about
whether the various files were case consistent. 

Then I ran into problems with packages and shadowing symbols from
when some of those symbols got interned. ( Plus, I still had to
make sure the code consistently used symbols. ) 

Then I switched back to strings and tried to check that they were
all case consistent. 

I never though to try keywords -- that sounds like it gets around
both problems. ( In other cases, I've found that leaning towards
using keyword symbols where possible ( or explicit packages in 
other cases ) has helped to avoid unpleasant surprises when 
EQ tests are done on symbols in different packages. 


---|  Steven D. Majewski   (804-982-0831)  <·····@Virginia.EDU>  |---
---|  Department of Molecular Physiology and Biological Physics  |---
---|  University of Virginia             Health Sciences Center  |---
---|  P.O. Box 10011            Charlottesville, VA  22906-0011  |---
	"Nature and Nature's laws lay hid in night:
	God said, let Newton be! and all was light." - pope
From: Erik Naggum
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <3100502077329521@naggum.no>
* Marco Antoniotti
| As an aside, I see also that using strings in package related functions
| and macros for package names and symbol names is a *good* thing.

* Erik Naggum
| uhm?  why?  using strings interferes with case massaging in the Lisp
| reader.  the only advantage is that no new symbols are created, but using
| uninterned symbols or keywords (for package names) isn't _that_ much
| trouble, is it?

  thanks to Kent Pitman, Marco Antoniotti, and Tim Bradshaw for their
  comments.  the reason for my concern is a little involved, so let me
  explain.  I use Franz Inc's Allegro Common Lisp and it has a feature,
  called the "case mode", whereby symbols names may be downcased.  (this
  also makes APROPOS a lot easier to use.)  the reason I switched to use
  "case-sensitive-lower" (as it is called) as the preferred case was that
  the Lisp printer in ACL doesn't quite follow the specification when
  *PRINT-CASE* and READTABLE-CASE settings differ from the defaults, and I
  really don't want to read symbol names in all caps (except in prose text
  where they are meant to stand out).  therefore, I also switched to using
  uninterned symbols in DEFPACKAGE.  I agree with Tim that it has a certain
  grotesque flavor to it, but I saw it as better than the name conflicts
  that would follow from using the wrong case when "hard-wiring" the case
  of symbols names.  however, upon thinking a bit more about this, spurred
  by the comments I received, I have returned to "case-insensitive-upper"
  as the preferred case mode and switched to using strings in DEFPACKAGE
  and other such forms.  thanks, guys.  *PRINT-CASE* is :DOWNCASE.  I'll
  see if I can unlearn the habit of using APROPOS on lower-case strings.

#:Erik
-- 
  (defmacro pretty-loop (&rest parenthesized-forms)
    "Make the dream that each LOOP clause be parenthesized come true."
    `(loop ,@(apply #'append parenthesized-forms)))
From: Jason Trenouth
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <352a6fb7.585822093@newshost>
On 02 Apr 1998 10:34:37 +0000, Erik Naggum <······@naggum.no> wrote:

> I'll see if I can unlearn the habit of using APROPOS on lower-case strings.

LispWorks' APROPOS is case insensitive for this very reason.

__Jason
From: P. Srinivas
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <6g0aob$fr3$1@tribune.usask.ca>
Jason Trenouth (·····@harlequin.com) wrote:
: On 02 Apr 1998 10:34:37 +0000, Erik Naggum <······@naggum.no> wrote:

: > I'll see if I can unlearn the habit of using APROPOS on 
: > lower-case strings.

: LispWorks' APROPOS is case insensitive for this very reason.

How about using symbol as an argument for APROPOS? This adds one extra
symbol for each call to APROPOS, but does take care of the case
problem.


Srini
--------------------
Srinivas Palthepu                       Email: ·····@cs.usask.ca
ARIES laboratory,                      Phones: (306) 966-8654 (lab)
Department of Computer Science,                (306) 966-4759 (office)
University of Saskatchewan,                    (306) 373-6724 (home)    
57 Campus Dr, Saskatoon, SK, S7N 5A9      Fax: (306) 966-4884
From: Espen Vestre
Subject: Re: Overwriting Functions/Macros?
Date: 
Message-ID: <w6k998e6vf.fsf@gromit.nextel.no>
Erik Naggum <······@naggum.no> writes:

>   and other such forms.  thanks, guys.  *PRINT-CASE* is :DOWNCASE.  I'll
>   see if I can unlearn the habit of using APROPOS on lower-case strings.

I'll probably be accused of severe misuse of the keyword package,
but I still can't resist mentioning that I use keywords as parameters
to apropos as well...

--

  (espen vestre)