From: Leo
Subject: Elisp defalias equivalent in CL?
Date: 
Message-ID: <m07hz8xwkh.fsf@cam.ac.uk>
Hi there,

I want to give a long function name an alias. For example

(defun cyan-magenta-yellow-black (c m y k)
  123456)

After asking in #lisp, it seems I can do

(setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)

However, this only gets a snapshot of the original function.

If I change the definition of cyan-magenta-yellow-black, cmyk won't
change.

Another approach suggested is by using

(defun cmyk (&rest args)
  (apply cyan-magenta-yellow-black args))

but then in slime you won't see the real arguments to the function, the
useful hint in the echo area.

Thus my question, is there something equivalent to defalias in Elisp?
Thank you. -- Leo

-- 
Emacs uptime: 1 day, 11 hours, 16 minutes, 10 seconds

From: fortunatus
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <593029ee-0810-47ba-8e1b-3731d7b1023a@p4g2000vba.googlegroups.com>
why doesn't


(defmacro  cymk (&rest  args)
  `(cyan-yellow-magenta-black ,@args))


solve the problem?
From: Leo
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <m0vdmsw4fr.fsf@cam.ac.uk>
On 2009-06-19 17:50 +0100, fortunatus wrote:
> why doesn't
>
>
> (defmacro  cymk (&rest  args)
>   `(cyan-yellow-magenta-black ,@args))
>
>
> solve the problem?

As stated in my original post, in slime you get a useless hint in the
echo area if cymk is defined that way.

-- 
Emacs uptime: 1 day, 16 hours, 18 minutes, 33 seconds
From: Tim Bradshaw
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <edfa2b52-ed71-4626-9bb8-caab8c09d6ac@f16g2000vbf.googlegroups.com>
On Jun 19, 1:00 pm, Leo <·······@gmail.com> wrote:
> Hi there,
>
> I want to give a long function name an alias. For example
>

The serious approach to this has two parts:

1. Construct a copy of the CL package where DEFUN is its own symbol
(use conduits or whatever suits).  Make this DEFUN a macro which
expands into something which stashes the argument list.  Soemthing
like:

(defun frabonot (bog &key brush) ...) ->
(progn
  (stash 'frabnot 'function '(bog &key brush))
  (cl:defun frabnot ...))

(I have not got the compile/load/eval-time stuff right here)

2. Your DEFALIAS now uses information kept by STASH to have the right
arglist.  However this is still a bit fiddly - you probably need to
add a rest arg which you hand to the original function, and need to
think about whether that list can be declared dynamic-extent.
From: Brian - qbg
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <bd7b644a-0b54-457e-bd9f-bcc8c649e445@l21g2000vba.googlegroups.com>
On Jun 19, 7:00 am, Leo <·······@gmail.com> wrote:
> Another approach suggested is by using
>
> (defun cmyk (&rest args)
>   (apply cyan-magenta-yellow-black args))
>
> but then in slime you won't see the real arguments to the function, the
> useful hint in the echo area.
Possible non-tested non-portable solution: defalias does the above,
but also stores the resulting function object into a weak #'eq
hashtable as the key and 'cyan-magenta-yellow-black as the value.
Then then replace the implementation-dependent function for getting
the arguments of a function (or if swank has such a function, you
replace that one) with a function that checks to see if the function
is in the hashtable, and if it is call the original function on the
alias, otherwise call the original function on the function.
From: Pascal Costanza
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <7a1fj5F1pbuifU1@mid.individual.net>
Leo wrote:
> Hi there,
> 
> I want to give a long function name an alias. For example
> 
> (defun cyan-magenta-yellow-black (c m y k)
>   123456)
> 
> After asking in #lisp, it seems I can do
> 
> (setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)
> 
> However, this only gets a snapshot of the original function.
> 
> If I change the definition of cyan-magenta-yellow-black, cmyk won't
> change.
> 
> Another approach suggested is by using
> 
> (defun cmyk (&rest args)
>   (apply cyan-magenta-yellow-black args))
> 
> but then in slime you won't see the real arguments to the function, the
> useful hint in the echo area.
> 
> Thus my question, is there something equivalent to defalias in Elisp?

It may be possible to implement it, but I'm not aware that it exists.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Tobias C. Rittweiler
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <87skhwc8ut.fsf@freebits.de>
Pascal Costanza <··@p-cos.net> writes:

> It may be possible to implement it, but I'm not aware that it exists.

It used to exist on Lisp machines which supported forwarding, or
invisible, pointers. :-)

  -T.
From: Pascal Costanza
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <7a3mvqF1mmj6mU1@mid.individual.net>
Tobias C. Rittweiler wrote:
> Pascal Costanza <··@p-cos.net> writes:
> 
>> It may be possible to implement it, but I'm not aware that it exists.
> 
> It used to exist on Lisp machines which supported forwarding, or
> invisible, pointers. :-)

Sure. Everything already existed on the Lisp machines... ;)


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Pascal J. Bourguignon
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <87iqisfjde.fsf@galatea.local>
Leo <·······@gmail.com> writes:

> Hi there,
>
> I want to give a long function name an alias. For example
>
> (defun cyan-magenta-yellow-black (c m y k)
>   123456)
>
> After asking in #lisp, it seems I can do
>
> (setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)
>
> However, this only gets a snapshot of the original function.
>
> If I change the definition of cyan-magenta-yellow-black, cmyk won't
> change.
>
> Another approach suggested is by using
>
> (defun cmyk (&rest args)
>   (apply cyan-magenta-yellow-black args))
>
> but then in slime you won't see the real arguments to the function, the
> useful hint in the echo area.

(defmacro defalias (new old)
  `(if (function-lambda-expression (function ,old))
      (defun ,new ,(function-lambda-expression (function ,old))
          (funcall (function ,old)
                 ,@(extract-arguments (function-lambda-expression (function ,old)))))
      (defun ,new (&rest args)
          (apply (function ,old) args))))

You just have to implement EXTRACT-ARGUMENTS
(have a look at make-argument-list and parse-lambda-list in 
http://darcs.informatimago.com/public/lisp/common-lisp/source-form.lisp
)


-- 
__Pascal Bourguignon__
From: blandest
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <1a4e0978-c8e6-4975-a42b-52ebb2ad2065@n8g2000vbb.googlegroups.com>
What does #'function-lambda-expression do anyway ? CLHS says that it
can return nil (implementation-dependent), which it does on ccl.
But it prints something similar to the source code of the function on
clisp. I guess it won't work all implementations ...

On Jun 19, 4:22 pm, ····@informatimago.com (Pascal J. Bourguignon)
wrote:
> Leo <·······@gmail.com> writes:
> > Hi there,
>
> > I want to give a long function name an alias. For example
>
> > (defun cyan-magenta-yellow-black (c m y k)
> >   123456)
>
> > After asking in #lisp, it seems I can do
>
> > (setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)
>
> > However, this only gets a snapshot of the original function.
>
> > If I change the definition of cyan-magenta-yellow-black, cmyk won't
> > change.
>
> > Another approach suggested is by using
>
> > (defun cmyk (&rest args)
> >   (apply cyan-magenta-yellow-black args))
>
> > but then in slime you won't see the real arguments to the function, the
> > useful hint in the echo area.
>
> (defmacro defalias (new old)
>   `(if (function-lambda-expression (function ,old))
>       (defun ,new ,(function-lambda-expression (function ,old))
>           (funcall (function ,old)
>                  ,@(extract-arguments (function-lambda-expression (function ,old)))))
>       (defun ,new (&rest args)
>           (apply (function ,old) args))))
>
> You just have to implement EXTRACT-ARGUMENTS
> (have a look at make-argument-list and parse-lambda-list inhttp://darcs.informatimago.com/public/lisp/common-lisp/source-form.lisp
> )
>
> --
> __Pascal Bourguignon__
From: Pascal J. Bourguignon
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <87eitgf9s8.fsf@galatea.local>
blandest <··············@gmail.com> writes:

> What does #'function-lambda-expression do anyway ? CLHS says that it
> can return nil (implementation-dependent), which it does on ccl.
> But it prints something similar to the source code of the function on
> clisp. I guess it won't work all implementations ...

Yes, that's why I tested for (function-lambda-expression (function ,old)), 
and provided another implementation in the case where it's nil.

Unfortunately, it fails when the old function changes its lambda-list,
see Pascal's answer.

-- 
__Pascal Bourguignon__
From: Pascal Costanza
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <7a1iakF1sut0bU1@mid.individual.net>
Pascal J. Bourguignon wrote:
> Leo <·······@gmail.com> writes:
> 
>> Hi there,
>>
>> I want to give a long function name an alias. For example
>>
>> (defun cyan-magenta-yellow-black (c m y k)
>>   123456)
>>
>> After asking in #lisp, it seems I can do
>>
>> (setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)
>>
>> However, this only gets a snapshot of the original function.
>>
>> If I change the definition of cyan-magenta-yellow-black, cmyk won't
>> change.
>>
>> Another approach suggested is by using
>>
>> (defun cmyk (&rest args)
>>   (apply cyan-magenta-yellow-black args))
>>
>> but then in slime you won't see the real arguments to the function, the
>> useful hint in the echo area.
> 
> (defmacro defalias (new old)
>   `(if (function-lambda-expression (function ,old))
>       (defun ,new ,(function-lambda-expression (function ,old))
>           (funcall (function ,old)
>                  ,@(extract-arguments (function-lambda-expression (function ,old)))))
>       (defun ,new (&rest args)
>           (apply (function ,old) args))))
> 
> You just have to implement EXTRACT-ARGUMENTS
> (have a look at make-argument-list and parse-lambda-list in 
> http://darcs.informatimago.com/public/lisp/common-lisp/source-form.lisp
> )

This may not reflect changes to the original function definition, and 
can especially break if the lambda list of the original function changes.

See also Section 3.2.2.3 in the HyperSpec.


Pascal

-- 
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Leo
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <m0zlc4w4i7.fsf@cam.ac.uk>
On 2009-06-19 14:22 +0100, Pascal J. Bourguignon wrote:
> (defmacro defalias (new old)
>   `(if (function-lambda-expression (function ,old))
>       (defun ,new ,(function-lambda-expression (function ,old))
>           (funcall (function ,old)
>                  ,@(extract-arguments (function-lambda-expression (function ,old)))))
>       (defun ,new (&rest args)
>           (apply (function ,old) args))))
>
> You just have to implement EXTRACT-ARGUMENTS
> (have a look at make-argument-list and parse-lambda-list in 
> http://darcs.informatimago.com/public/lisp/common-lisp/source-form.lisp
> )

On 2009-06-19 15:14 +0100, blandest wrote:
> What does #'function-lambda-expression do anyway ? CLHS says that it
> can return nil (implementation-dependent), which it does on ccl.
> But it prints something similar to the source code of the function on
> clisp. I guess it won't work all implementations ...

On 2009-06-19 14:32 +0100, Pascal Costanza wrote:
> This may not reflect changes to the original function definition, and
> can especially break if the lambda list of the original function
> changes.
>
> See also Section 3.2.2.3 in the HyperSpec.
>
>
> Pascal

Many thanks for the hints and suggestions. I will go with the simplest
for now and decide whether that's sufficient later.

-- 
Emacs uptime: 1 day, 16 hours, 16 minutes, 6 seconds
From: Kaz Kylheku
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <20090701181104.435@gmail.com>
On 2009-06-19, Leo <·······@gmail.com> wrote:
> Hi there,
>
> I want to give a long function name an alias. For example
>
> (defun cyan-magenta-yellow-black (c m y k)
>   123456)
>
> After asking in #lisp, it seems I can do
>
> (setf (fdefinition 'cmyk) #'cyan-magenta-yellow-black)
>
> However, this only gets a snapshot of the original function.

But this is a simple synchronization problem that can be solved in
a general way. Write a comprehensive function aliasing system
which incorporates the notion of keeping track of alias definitions.

Your DEFALIAS will not only just stick the function into the symbol's
function binding, but also register the aliasing relationship
(and compute any transitive closures of the aliasing graph, to
identify sets of symbols which alias to the same function).

Then you can provide a simple function UPDATE-ALIASES which can be
called whenever functions are redefined anywhere in the program.

The function will walk the alias graphs, discover what has been
changed and propagate the function appropriately.

There is the potential for conflicts. Suppose A, B and C are all aliases for
the same function. B and C are independently redefined. UPDATE-ALIASES will
discover this: it will note that for the alias set {A B C}, A still has original
definition (its function binding is EQ to the original function), but two
functions B and C do not. In this case, a condition can be signaled, and
restarts provided, by which the condition handler can elect either B or C
to be the new definition for the entire alias set.
If only one function in an alias set is different, then that function
is automaticaly propagated to the entire set.

> If I change the definition of cyan-magenta-yellow-black, cmyk won't
> change.

Note that to deal with the nuisance of long names (and for other obvious
reasons), Common Lisp provides packages.

If you can split a long name into two parts---a package qualifier and
the name proper---that obviously helps you.

Another feature that helps is that CL provides for package name aliases
(called nicknames). For instance the "COMMON-LISP" package also has the
nickname "CL".

So if you are in a package where, say, the LIST function is shadowed
by a local symbol and you want to call the standard one,
you can use CL:LIST rather than COMMON-LISP:LIST.

> Another approach suggested is by using
>
> (defun cmyk (&rest args)
>   (apply cyan-magenta-yellow-black args))

You can make it a macro.

  (defmacro cmyk (&rest args) `(cyan-magenta-yellow-black ,@args))

But of course this isn't a function, so #'cmyk doesn't work.  Yet it does
satsiyf some semantic notions of alias. Obviously (cmyk args) calls the
original function; that function can be redefined, and the macro will follow.
From: Vassil Nikolov
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <snzfxduqkwz.fsf@luna.vassil.nikolov.name>
On Fri, 19 Jun 2009 13:00:30 +0100, Leo <·······@gmail.com> said:

> Hi there,
> I want to give a long function name an alias. For example [cmyk for]

> (defun cyan-magenta-yellow-black (c m y k)
>   123456)

  If you will _always_ change the function only by making changes to
  the original definition form and re-evaluating that (and if you can
  afford increased memory utilization), you can simply define a
  wrapper around DEFUN, so that

    (defun-aliased (cyan-magenta-yellow-black cmyk) (c m y k) 123456)

  macroexpands into

    (progn
      (defun cyan-magenta-yellow-black (c m y k) 123456)
      (defun cmyk (c m y k) 123456))

  (note that you will not have to change the definition forms
  themselves if in the future you change the way you implement
  aliasing, just the definition of DEFUN-ALIASED).

    ;; untested
    (defmacro defun-aliased (names &rest defdata)
      `(progn ,@(mapcar #'(lambda (n) `(defun ,n ,@defdata)) names)))

  Having said that, I don't know if the value of such aliases in
  Common Lisp programming is worth the candles.  In emacs, I only use
  aliases for interactive invocation of commands (with M-x) to save
  typing (where my aliases often start with characters that do not
  otherwise occur in the beginning of command names, reducing
  completion "noise"), but never in Elisp programs.

  ---Vassil.


-- 
Vassil Nikolov <········@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".
From: Kaz Kylheku
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <20090703053925.606@gmail.com>
On 2009-06-21, Vassil Nikolov <········@pobox.com> wrote:
>   Having said that, I don't know if the value of such aliases in
>   Common Lisp programming is worth the candles.

Aliases in programming are a liability. (Aliases of all kinds: alaised
names, aliased arrays egions, aliased cache lines, etc).

There is value in knowing that a given lookup key is the only means
of accessing something, such that any other identifier used in the
same context accesses something else.
From: Barry Margolin
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <barmar-0FB832.12452121062009@news.eternal-september.org>
In article <··················@gmail.com>,
 Kaz Kylheku <········@gmail.com> wrote:

> On 2009-06-21, Vassil Nikolov <········@pobox.com> wrote:
> >   Having said that, I don't know if the value of such aliases in
> >   Common Lisp programming is worth the candles.
> 
> Aliases in programming are a liability. (Aliases of all kinds: alaised
> names, aliased arrays egions, aliased cache lines, etc).
> 
> There is value in knowing that a given lookup key is the only means
> of accessing something, such that any other identifier used in the
> same context accesses something else.

Aliases are often useful for backward compatibility.  You decide to 
rename something, perhaps as part of a new, more consistent naming 
scheme, but you don't want to break all the users of the old name.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: ACL
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <8502896b-0ba9-409b-b8fb-b491deb7bb1a@l32g2000vba.googlegroups.com>
On Jun 21, 12:45 pm, Barry Margolin <······@alum.mit.edu> wrote:
> In article <··················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>
> > On 2009-06-21, Vassil Nikolov <········@pobox.com> wrote:
> > >   Having said that, I don't know if the value of such aliases in
> > >   Common Lisp programming is worth the candles.
>
> > Aliases in programming are a liability. (Aliases of all kinds: alaised
> > names, aliased arrays egions, aliased cache lines, etc).
>
> > There is value in knowing that a given lookup key is the only means
> > of accessing something, such that any other identifier used in the
> > same context accesses something else.
>
> Aliases are often useful for backward compatibility.  You decide to
> rename something, perhaps as part of a new, more consistent naming
> scheme, but you don't want to break all the users of the old name.
>
> --
> Barry Margolin, ······@alum.mit.edu
> Arlington, MA
> *** PLEASE post questions in newsgroups, not directly to me ***
> *** PLEASE don't copy me on replies, I'll read them in the group ***

Problem is 20 years down the line different devs have renamed things 4
or 5 times because of changing needs/requirements of the software and
you have 6 names for the same/similar thing(s).

Changes and bug fixes that would have been trivial become non-trivial.

Refactoring has a bigger long term payoff.
(even if in short term it seems like a chore).
From: Vassil Nikolov
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <snz7hz5qn4p.fsf@luna.vassil.nikolov.name>
On Sun, 21 Jun 2009 09:56:07 -0700 (PDT), ACL <··················@gmail.com> said:

> On Jun 21, 12:45 pm, Barry Margolin <······@alum.mit.edu> wrote:
>> In article <··················@gmail.com>, Kaz Kylheku <········@gmail.com> wrote:
>> 
>> > On 2009-06-21, Vassil Nikolov <········@pobox.com> wrote:
>> > >  Having said that, I don't know if the value of such aliases in
>> > >  Common Lisp programming is worth the candles.
>> 
>> > Aliases in programming are a liability. (Aliases of all kinds: alaised
>> > names, aliased arrays egions, aliased cache lines, etc).
>> 
>> > There is value in knowing that a given lookup key is the only means
>> > of accessing something, such that any other identifier used in the
>> > same context accesses something else.
>> 
>> Aliases are often useful for backward compatibility.  You decide to
>> rename something, perhaps as part of a new, more consistent naming
>> scheme, but you don't want to break all the users of the old name.

> Problem is 20 years down the line different devs have renamed things 4
> or 5 times because of changing needs/requirements of the software and
> you have 6 names for the same/similar thing(s).

> Changes and bug fixes that would have been trivial become non-trivial.

> Refactoring has a bigger long term payoff.
> (even if in short term it seems like a chore).

  Indeed one needs to know well what kind of trade-off one wants with
  respect to the above considerations in one's particular case, and
  there isn't a one-size-fits-all answer (sometimes immediate
  refactoring is not just a chore, but prohibitively expensive when
  the ripple effects are taken into account, especially when writing
  libraries, rather than applications).

  It seems, though, that the original post was about introducing a
  short alias _at the same time_ as the primary name (is there any
  need for hints about parameters when using aliases for backward
  compatibility?), and given the availability of completion etc., I
  don't know if _that_ use of aliases is sufficiently justified.  At
  the very least, one would have to make sure they are only used for
  debugging and experimentation, but not in the source.

  ---Vassil.


-- 
Vassil Nikolov <········@pobox.com>

  (1) M(Gauss);
  (2) M(a) if M(b) and declared(b, M(a)),
  where M(x) := "x is a mathematician".
From: Kaz Kylheku
Subject: Re: Elisp defalias equivalent in CL?
Date: 
Message-ID: <20090704031822.424@gmail.com>
On 2009-06-21, Barry Margolin <······@alum.mit.edu> wrote:
> In article <··················@gmail.com>,
>  Kaz Kylheku <········@gmail.com> wrote:
>
>> On 2009-06-21, Vassil Nikolov <········@pobox.com> wrote:
>> >   Having said that, I don't know if the value of such aliases in
>> >   Common Lisp programming is worth the candles.
>> 
>> Aliases in programming are a liability. (Aliases of all kinds: alaised
>> names, aliased arrays egions, aliased cache lines, etc).
>> 
>> There is value in knowing that a given lookup key is the only means
>> of accessing something, such that any other identifier used in the
>> same context accesses something else.
>
> Aliases are often useful for backward compatibility.  You decide to 
> rename something, perhaps as part of a new, more consistent naming 
> scheme, but you don't want to break all the users of the old name.

I tend to avoid this kind of nonproductive change. Some names are better
than others, but the consideration that a name is in use wins.

Ken Thompson said that he regretted one thing in Unix, and that was
the missing ``e'' in ``creat''. It's still not there now.

Aliases are useful for symbol hygiene, in a situation where users are allowed
to redefine public symbols. The implementation needs to have some alternate,
secret names by which it can refer to the original entities.

This kind of alias precisely has the opposite requirement from the one given in
at the root of this thread: it must /not/ follow redefinitions.