Overwriting Functions/Macros? 
Author Message
 Overwriting Functions/Macros?

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



Sat, 16 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?


| 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 {*filter*}er::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."



Sat, 16 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?


Quote:

>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.

--

GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.



Sun, 17 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:



> >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



Sun, 17 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

> 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))


       (progn ;mask the implicit tagbody supplied by cl:dotimes

(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.



Sun, 17 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?


Quote:

> (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



Sun, 17 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

* 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."



Sun, 17 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

> * 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.



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

> * 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



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

>   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



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

> 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



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

* 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."



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?


Quote:
> 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



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?

Quote:

>   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)



Mon, 18 Sep 2000 03:00:00 GMT  
 Overwriting Functions/Macros?


: > 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
--------------------

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



Mon, 18 Sep 2000 03:00:00 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. A macro involving two sub-macros - where the 2nd macro needs results from the first

2. Realbasic instead of VB in Excel function macro?

3. do CW have macro function like foxpro

4. Can't Call Static Function With Macro????

5. APIs, Functions, & Macros

6. Haskell functions as CL/Scheme macros

7. Using HD COM macros for accessing MAPI functions

8. OS/2 Rexx Macro Space functions (use with RXU utility pkg)

9. Haskell functions as CL/Scheme macros

10. Macro/Function in VHDL testbench ?

11. inline functions or macros?

12. Call Python functions from C[++] as macros

 

 
Powered by phpBB® Forum Software