I'd like to use a macro or function definition to redefine the
(make-pathname :name "foo" :type "fum") function to work like
(make-pathname :name "fum" :type "foo"). All other functionality
should remain unchanged. Can you help?
Carlo
On Sep 20, 7:39 am, Carlo Capocasa <······@carlocapocasa.com> wrote:
> I'd like to use a macro or function definition to redefine the
> (make-pathname :name "foo" :type "fum") function to work like
> (make-pathname :name "fum" :type "foo"). All other functionality
> should remain unchanged. Can you help?
Probably. Look up SHADOW in the CLHS, and use &ALLOW-OTHER-KEYS.
But why on Earth do you want to do this?
Cheers,
Pillsy
On Sep 20, 11:51 am, Carlo Capocasa <······@carlocapocasa.com> wrote:
> > But why on Earth do you want to do this?
> Power.
Well, if you just want to know you can do it, just shadow the original
name and wrap CL:MAKE-PATHNAME with a function that does whatever you
want to the arguments beforehand.
Cheers,
Pillsy
> Well, if you just want to know you can do it, just shadow the original
> name and wrap CL:MAKE-PATHNAME with a function that does whatever you
> want to the arguments beforehand.
Thanks!
I also have another reason: in ECL, make-pathname behaves
differently from SBCL and I want to make the same code work in both
implementations by redefining the function with a #+ecl.
Consider you have these files in /tmp:
a.lisp
a.b.lisp
a.b.c.lisp
a.b.c.d.lisp
a.b.c.d.e.lisp
in SBCL (and CLISP too), running:
(directory
(make-pathname
:name :wild
:type "lisp"
:version :wild
:directory '(:absolute "tmp")))
will yield
(#P"/tmp/a.b.c.d.e.lisp" #P"/tmp/a.b.c.d.lisp" #P"/tmp/a.b.c.lisp"
#P"/tmp/a.b.lisp" #P"/tmp/a.lisp")
in ECL, the same call will return
(#P"/tmp/a.lisp")
while replacing :type with "b.lisp", "b.c.lisp", "b.c.d.lisp",
"b.c.d.e.lisp" will return "a.b.lisp", "a.b.c.lisp", "a.b.c.d.lisp"
and "a.b.c.d.e.lisp" respectively.
Carlo
Carlo Capocasa <······@carlocapocasa.com> writes:
> I'd like to use a macro or function definition to redefine the
> (make-pathname :name "foo" :type "fum") function to work like
> (make-pathname :name "fum" :type "foo"). All other functionality
> should remain unchanged. Can you help?
But why?
In any case, taking advantage of the keyword argument shadowing in CL:
(defun make-mutant-pathname (&key name type &rest args)
(apply #'make-pathname :name name :type type args))
--
Thomas A. Russ, USC/Information Sciences Institute
> But why?
I want to train ECL's make-pathname to behave like SBCLs.
Consider you have these files in /tmp:
a.lisp
a.b.lisp
a.b.c.lisp
a.b.c.d.lisp
a.b.c.d.e.lisp
in SBCL (and CLISP too), running:
(directory
(make-pathname
:name :wild
:type "lisp"
:version :wild
:directory '(:absolute "tmp")))
will yield
(#P"/tmp/a.b.c.d.e.lisp" #P"/tmp/a.b.c.d.lisp" #P"/tmp/a.b.c.lisp"
#P"/tmp/a.b.lisp" #P"/tmp/a.lisp")
in ECL, the same call will return
(#P"/tmp/a.lisp")
while replacing :type with "b.lisp", "b.c.lisp", "b.c.d.lisp",
"b.c.d.e.lisp" will return "a.b.lisp", "a.b.c.lisp", "a.b.c.d.lisp"
and "a.b.c.d.e.lisp" respectively.
Carlo
In article <············@registered.motzarella.org>,
Carlo Capocasa <······@carlocapocasa.com> wrote:
> > But why?
>
> I want to train ECL's make-pathname to behave like SBCLs.
>
> Consider you have these files in /tmp:
>
> a.lisp
> a.b.lisp
> a.b.c.lisp
> a.b.c.d.lisp
> a.b.c.d.e.lisp
>
> in SBCL (and CLISP too), running:
>
> (directory
> (make-pathname
> :name :wild
> :type "lisp"
> :version :wild
> :directory '(:absolute "tmp")))
>
> will yield
>
> (#P"/tmp/a.b.c.d.e.lisp" #P"/tmp/a.b.c.d.lisp" #P"/tmp/a.b.c.lisp"
> #P"/tmp/a.b.lisp" #P"/tmp/a.lisp")
>
> in ECL, the same call will return
>
> (#P"/tmp/a.lisp")
>
> while replacing :type with "b.lisp", "b.c.lisp", "b.c.d.lisp",
> "b.c.d.e.lisp" will return "a.b.lisp", "a.b.c.lisp", "a.b.c.d.lisp"
> and "a.b.c.d.e.lisp" respectively.
>
> Carlo
Complain about that to the ECL maintainer. It would be
good if on Unix (and related) implementations somehow
behave similar when dealing with pathnames.
--
http://lispm.dyndns.org
> Complain about that to the ECL maintainer. It would be
> good if on Unix (and related) implementations somehow
> behave similar when dealing with pathnames.
I did!
Carlo Capocasa <······@carlocapocasa.com> writes:
> > But why?
>
> I want to train ECL's make-pathname to behave like SBCLs.
But swapping name and type won't make it work.
That's because MAKE-PATHNAME undoubtedly works exactly the same way in
both implementations. The problem is that the mapping of file
namestrings to pathnames works differently. But that is an area that is
implementation dependent.
The place you need to focus attention is on the PATHNAME function, which
is used to translate namestrings to pathnames. You can observe this by
trying
(describe (pathname "a.b.c.lisp"))
in the two implementations.
> Consider you have these files in /tmp:
>
> a.lisp
> a.b.lisp
> a.b.c.lisp
> a.b.c.d.lisp
> a.b.c.d.e.lisp
>
> in SBCL (and CLISP too), running:
>
> (directory
> (make-pathname
> :name :wild
> :type "lisp"
> :version :wild
> :directory '(:absolute "tmp")))
>
> will yield
>
> (#P"/tmp/a.b.c.d.e.lisp" #P"/tmp/a.b.c.d.lisp" #P"/tmp/a.b.c.lisp"
> #P"/tmp/a.b.lisp" #P"/tmp/a.lisp")
Yes. The issue here is not with the pathname that is constructed but
rather with the pathname mapping. So, it would be perhaps better to
focus on trying to change the behavior of PATHNAME instead.
What may be useful is if ECL (which I've never used) has anything like
an ADVISE or ADVICE capability, which would allow you to write a wrapper
around the existing pathname function. That would then allow you to
modify what it produces to get the effects that you want.
> in ECL, the same call will return
>
> (#P"/tmp/a.lisp")
>
> while replacing :type with "b.lisp", "b.c.lisp", "b.c.d.lisp",
> "b.c.d.e.lisp" will return "a.b.lisp", "a.b.c.lisp", "a.b.c.d.lisp"
> and "a.b.c.d.e.lisp" respectively.
>
> Carlo
--
Thomas A. Russ, USC/Information Sciences Institute
> But swapping name and type won't make it work.
Oh yeah I meant that as a partial solution.
> That's because MAKE-PATHNAME undoubtedly works exactly the same way in
> both implementations. The problem is that the mapping of file
> namestrings to pathnames works differently. But that is an area that is
> implementation dependent.
>
> The place you need to focus attention is on the PATHNAME function, which
> is used to translate namestrings to pathnames. You can observe this by
> trying
>
> (describe (pathname "a.b.c.lisp"))
>
> in the two implementations.
Wow, that's some extremely valuable information that would probably
have taken days in frustration to gather, thanks!
> Yes. The issue here is not with the pathname that is constructed but
> rather with the pathname mapping. So, it would be perhaps better to
> focus on trying to change the behavior of PATHNAME instead.
Great!
> What may be useful is if ECL (which I've never used) has anything like
> an ADVISE or ADVICE capability, which would allow you to write a wrapper
> around the existing pathname function. That would then allow you to
> modify what it produces to get the effects that you want.
That's exactly the functionality I was looking for.
ECL doesn't obviously have the capability but I'd need to research a
little more to say for sure. Could it be done with a macro instead?
Carlo
On Sep 21, 5:37 am, Carlo Capocasa <······@carlocapocasa.com> wrote:
> I want to trainECL'smake-pathname to behave like SBCLs.
> Consider you have these files in /tmp:
> a.lisp
> a.b.lisp
> a.b.c.lisp
> a.b.c.d.lisp
> a.b.c.d.e.lisp
> in SBCL (and CLISP too), running:
> (directory
> (make-pathname
> :name :wild
> :type "lisp"
> :version :wild
> :directory '(:absolute "tmp")))
> will yield
> (#P"/tmp/a.b.c.d.e.lisp" #P"/tmp/a.b.c.d.lisp" #P"/tmp/a.b.c.lisp"
> #P"/tmp/a.b.lisp" #P"/tmp/a.lisp")
> inECL, the same call will return
> (#P"/tmp/a.lisp")
Hi, this is to clarify that this error is not present in the CVS
version of ECL. I do not know what version you are running (I already
asked in the mailing list without getting an answer) and I do not
recall this happening in any recent version. Here is what I get
running ECL on an Ubuntu/x86 machine:
········@pcgordo:~$ mkdir /tmp/foo
········@pcgordo:~$ touch /tmp/foo/a.lisp
········@pcgordo:~$ touch /tmp/foo/a.b.lisp
········@pcgordo:~$ touch /tmp/foo/a.b.c.lisp
········@pcgordo:~$ touch /tmp/foo/a.b.c.d.lisp
········@pcgordo:~$ touch /tmp/foo/a.b.c.d.e.lisp
········@pcgordo:~$ ecl
;;; Loading #P"/home/jjgarcia/lib/ecl/asdf.fas"
ECL (Embeddable Common-Lisp) 0.9i
Copyright (C) 1984 Taiichi Yuasa and Masami Hagiya
Copyright (C) 1993 Giuseppe Attardi
Copyright (C) 2000 Juan J. Garcia-Ripoll
ECL is free software, and you are welcome to redistribute it
under certain conditions; see file 'Copyright' for details.
Type :h for Help. Top level.
> (directory
(make-pathname
:name :wild
:type "lisp"
:version :wild
:directory '(:absolute "tmp" "foo")))
(#P"/tmp/foo/a.b.c.d.e.lisp" #P"/tmp/foo/a.b.c.d.lisp" #P"/tmp/foo/
a.b.c.lisp"
#P"/tmp/foo/a.b.lisp" #P"/tmp/foo/a.lisp")
Cheers,
Juanjo
> (defun make-mutant-pathname (&key name type &rest args)
> (apply #'make-pathname :name name :type type args))
Hm, I'm getting an error on
(apply #'make-pathname :name name :type type args))
> Hm, I'm getting an error on
>
> (apply #'make-pathname :name name :type type args))
That should be (apply #'make-pathname
`(:name ,name :type ,type ,@args)))
AS
In article <·······················@o80g2000hse.googlegroups.com>,
Alessio <·············@gmail.com> wrote:
> > Hm, I'm getting an error on
> >
> > (apply #'make-pathname :name name :type type args))
>
> That should be (apply #'make-pathname
> `(:name ,name :type ,type ,@args)))
>
> AS
? (let ((name "foo")
(type "text")
(args (list :directory (list :absolute "bar"))))
(apply #'make-pathname :name name :type type args))
#P"/bar/foo.text"
Works fine for me... APPLY takes a 'spreadable argument list designator'.
http://lispm.dyndns.org/documentation/HyperSpec-7-0/HyperSpec/Body/f_apply.htm#apply
--
http://lispm.dyndns.org
> Works fine for me... APPLY takes a 'spreadable argument list designator'.
>
> http://lispm.dyndns.org/documentation/HyperSpec-7-0/HyperSpec/Body/f_...
Cool! I didn't know that. You always learn new things by carefully
reading the HyperSpec...
AS
Rainer Joswig <······@lisp.de> writes:
> In article <·······················@o80g2000hse.googlegroups.com>,
> Alessio <·············@gmail.com> wrote:
>
> > > Hm, I'm getting an error on
> > >
> > > (apply #'make-pathname :name name :type type args))
> >
> > That should be (apply #'make-pathname
> > `(:name ,name :type ,type ,@args)))
> >
>
> ? (let ((name "foo")
> (type "text")
> (args (list :directory (list :absolute "bar"))))
> (apply #'make-pathname :name name :type type args))
>
> #P"/bar/foo.text"
>
>
> Works fine for me... APPLY takes a 'spreadable argument list designator'.
>
> http://lispm.dyndns.org/documentation/HyperSpec-7-0/HyperSpec/Body/f_apply.htm#apply
And, in fact, this definition of APPLY dovetails nicely with the rules
for keyword shadowing in lambda list parsing, in part to allow a
convenient way to override other keyword arguments. To see that in
action, you can easily invoke:
(apply #'make-pathname :name "front" :type "text"
'(:directory (:absolute "bar") :name "back"))
Note that the keyword :NAME appears more than once.
The shadowing effect frees you from the need to remove any keywords you
want to shadow from the parameter list when doing such processing.
--
Thomas A. Russ, USC/Information Sciences Institute