From: George Smith
Subject: logical pathnames and CMU CL
Date: 
Message-ID: <363F06D5.CE6D1ABF@hockett.phil1.uni-potsdam.de>
I think I must be misunderstanding something regarding logical
pathnames. Since some things relating to logical pathnames are
implementation dependent, it might be worth noting that I am usin CMU
CL 18a under Solaris 2.5.


When I try to adapt the simplest example in CLtL2 to unix CMU CL does
the following:

* (setf (logical-pathname-translations "foo") 
      '(("**;*.*.*"          "/lib/prog/")))

(("**;*.*.*" "/lib/prog/"))
* (translate-logical-pathname "foo:bar;baz;mum.quux.3")

#p"/lib/prog/mum.quux.3"

I would have expected #p"/lib/prog/bar/baz/mum.quux.3"

The implementation specific example which Steele gives here is:

(setf (logical-pathname-translations "foo") 
      '(("**;*.*.*"          "MY-LISPM:>library>foo>**>"))) 

(translate-logical-pathname "foo:bar;baz;mum.quux.3") 
   => #P"MY-LISPM:>library>foo>bar>baz>mum.quux.3"


When I try the following, CMU CL does this:

* (setf (logical-pathname-translations "prog")
       '(("CODE;*.*.*"             "/lib/prog/")))

(("CODE;*.*.*" "/lib/prog/"))
* (translate-logical-pathname "prog:code;documentation.lisp")

#p"/lib/prog/documentation.lisp"
* (translate-logical-pathname
"prog:code;new-project;documentation.lisp")

Error in function TRANSLATE-LOGICAL-PATHNAME:
   No translation for #.(logical-pathname
"PROG:CODE;NEW-PROJECT;DOCUMENTATION.LISP")

Restarts:
  0: [ABORT] Return to Top-Level.

I expected #p"/lib/prog/documentation.lisp", but I'm not sure why an
error is signaled when evaluating:

   (translate-logical-pathname
"prog:code;new-project;documentation.lisp")

It seems to me that I get an error whenever I try to use more than one
directory in a logical pathname. Using more than one directory should
be possible (cf the following quote from the hyperspec).

logical-pathname::= [host host-marker]  
                    [relative-directory-marker] {directory
directory-marker}*  
                    [name] [type-marker type [version-marker version]]

Can anybody point me to whatever it is that I am misunderstanding? The
problem I have at hand is rather simple (and frequent): a subtree of a
file system contains data which I need to access. The root of this
subtree may need to be moved around from time to time and I want to
use logical pathnames so that I can specify the root of the tree in
one place and only modify this one specification when the data is
moved.

Thanks in advance,

George Smith
············@hockett.phil1.uni-potsdam.de
Institut fuer Germanistik
Universitaet Potsdam

From: Raymond Toy
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <4nk91crf8g.fsf@rtp.ericsson.se>
>>>>> "George" == George Smith <············@hockett.phil1.uni-potsdam.de> writes:

    George> I think I must be misunderstanding something regarding logical
    George> pathnames. Since some things relating to logical pathnames are
    George> implementation dependent, it might be worth noting that I am usin CMU
    George> CL 18a under Solaris 2.5.


    George> When I try to adapt the simplest example in CLtL2 to unix CMU CL does
    George> the following:

    George> * (setf (logical-pathname-translations "foo") 
    George>       '(("**;*.*.*"          "/lib/prog/")))

    George> (("**;*.*.*" "/lib/prog/"))
    George> * (translate-logical-pathname "foo:bar;baz;mum.quux.3")

    George> #p"/lib/prog/mum.quux.3"

    George> I would have expected #p"/lib/prog/bar/baz/mum.quux.3"

You are right; this appears to be a bug.  I think CMUCL is not
correctly handling the directory parts of the pathname.

    George> The implementation specific example which Steele gives here is:

    George> (setf (logical-pathname-translations "foo") 
    George>       '(("**;*.*.*"          "MY-LISPM:>library>foo>**>"))) 

    George> (translate-logical-pathname "foo:bar;baz;mum.quux.3") 
    George>    => #P"MY-LISPM:>library>foo>bar>baz>mum.quux.3"

This fails perhaps for the same reason as above, but it might be
confused by the fact that CMUCL thinks MY-LISPM: is actually a
search-list, a CMUCL extension.

    George> When I try the following, CMU CL does this:

    George> * (setf (logical-pathname-translations "prog")
    George>        '(("CODE;*.*.*"             "/lib/prog/")))

    George> (("CODE;*.*.*" "/lib/prog/"))
    George> * (translate-logical-pathname "prog:code;documentation.lisp")

    George> #p"/lib/prog/documentation.lisp"
    George> * (translate-logical-pathname
    George> "prog:code;new-project;documentation.lisp")

    George> Error in function TRANSLATE-LOGICAL-PATHNAME:
    George>    No translation for #.(logical-pathname
    George> "PROG:CODE;NEW-PROJECT;DOCUMENTATION.LISP")

My reading of CLtL2 implies this is correct:  Your translation doesn't 
account for directories.  A translation like

(setf (logical-pathname-translations "prog")
      '(("CODE;**;*.*.*"             "/lib/prog/")))

appears to do what you want.

The logical pathname support is relatively new and hasn't been
well-tested.  This is complicated by the fact that CMUCL has it's own
search-list extension that uses similar syntax.

Ray
From: Marco Antoniotti
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <lwzpa7vpjx.fsf@copernico.parades.rm.cnr.it>
Raymond Toy <···@rtp.ericsson.se> writes:

>     George> (setf (logical-pathname-translations "foo") 
>     George>       '(("**;*.*.*"          "MY-LISPM:>library>foo>**>"))) 
> 
>     George> (translate-logical-pathname "foo:bar;baz;mum.quux.3") 
>     George>    => #P"MY-LISPM:>library>foo>bar>baz>mum.quux.3"
> 
> This fails perhaps for the same reason as above, but it might be
> confused by the fact that CMUCL thinks MY-LISPM: is actually a
> search-list, a CMUCL extension.

Which, as I tried to argue elsewhere is useless and pernicious, given
that logical pathnames are a superset of search lists.

I have been bitten by this before.

>     George> When I try the following, CMU CL does this:
> 
>     George> * (setf (logical-pathname-translations "prog")
>     George>        '(("CODE;*.*.*"             "/lib/prog/")))
> 
>     George> (("CODE;*.*.*" "/lib/prog/"))
>     George> * (translate-logical-pathname "prog:code;documentation.lisp")
> 
>     George> #p"/lib/prog/documentation.lisp"
>     George> * (translate-logical-pathname
>     George> "prog:code;new-project;documentation.lisp")
> 
>     George> Error in function TRANSLATE-LOGICAL-PATHNAME:
>     George>    No translation for #.(logical-pathname
>     George> "PROG:CODE;NEW-PROJECT;DOCUMENTATION.LISP")
> 
> My reading of CLtL2 implies this is correct:  Your translation doesn't 
> account for directories.  A translation like
> 
> (setf (logical-pathname-translations "prog")
>       '(("CODE;**;*.*.*"             "/lib/prog/")))
> 
> appears to do what you want.
> 
> The logical pathname support is relatively new and hasn't been
> well-tested.  This is complicated by the fact that CMUCL has it's own
> search-list extension that uses similar syntax.

This is a project worthwhile for anybody looking into CMUCL
guts. (Let's see if I can scrape off some time) Nuking the
pre-logical-pathname search lists and fixing logical pathnames
altogether.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Raymond Toy
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <4nhfwfr3yz.fsf@rtp.ericsson.se>
>>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

    Marco> Raymond Toy <···@rtp.ericsson.se> writes:

[snip]
    >> 
    >> This fails perhaps for the same reason as above, but it might be
    >> confused by the fact that CMUCL thinks MY-LISPM: is actually a
    >> search-list, a CMUCL extension.

    Marco> Which, as I tried to argue elsewhere is useless and pernicious, given
    Marco> that logical pathnames are a superset of search lists.

    Marco> I have been bitten by this before.

But search-lists do things that logical pathnames can't, right?
Search-lists works like PATH does for a shell.  Logical pathnames
don't.

[snip]
	
    >> The logical pathname support is relatively new and hasn't been
    >> well-tested.  This is complicated by the fact that CMUCL has it's own
    >> search-list extension that uses similar syntax.

    Marco> This is a project worthwhile for anybody looking into CMUCL
    Marco> guts. (Let's see if I can scrape off some time) Nuking the
    Marco> pre-logical-pathname search lists and fixing logical pathnames
    Marco> altogether.

I have to say, I rather like the search-lists.  I only use them for
building CMUCL where I can easily shadow other directories and build
it in different places with minimal changes.  For my code, I try to
use logical pathnames since they're portable, more or less.

Ray
From: Marco Antoniotti
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <lwyapruwln.fsf@copernico.parades.rm.cnr.it>
Raymond Toy <···@rtp.ericsson.se> writes:

> >>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
> 
>     Marco> Raymond Toy <···@rtp.ericsson.se> writes:
> 
> [snip]
>     >> 
>     >> This fails perhaps for the same reason as above, but it might be
>     >> confused by the fact that CMUCL thinks MY-LISPM: is actually a
>     >> search-list, a CMUCL extension.
> 
>     Marco> Which, as I tried to argue elsewhere is useless and pernicious, given
>     Marco> that logical pathnames are a superset of search lists.
> 
>     Marco> I have been bitten by this before.
> 
> But search-lists do things that logical pathnames can't, right?
> Search-lists works like PATH does for a shell.  Logical pathnames
> don't.

That is true,... but

1 - search lists seems to be used only in a way that is subsumed by
    logical-pathnames. This is the list I have in my Solaris
    installation basic installation

    * (dolist (s (get-search-lists-keys)
         (ignore-errors
             (format t "> ~A: ~S~%"
                     s
                     (search-list (concatenate 'string s ":")))))
    > home: (#p"/users/marcoxa/")
    > default: (#p"/users/marcoxa/lang/cl/")
    > target: (#p"/users/marcoxa/lang/cl/cmucl/src/")
    > modules: (#p"default:./")
    > path: (#p"/usr/openwin/bin/" #p"/software/netscape/"
             #p"/software/public/xv/bin/" #p"/software/public/prcs/bin/"
             #p"/projects/ptolemy/ptolemy-0.7/bin.sol2.5/"
		....
             #p"/opt/hpnp/bin/")
    > library: (#p"/software/public/cmucl/lib/")
    NIL

    Apart from the "path:" search list (derived from my shell
    variable) the other search lists can be replaced with a regular
    logical pathname, which does not even have to use 'wild inferiors'.

2 - they are non standard and may interfere with a standard (alas,
    implementation dependent) feature of the language. Programs using
    logical pathnames may be portable. Programs using the 'path'
    search lists feature surely will not.

I am not particularly happy with the whole logical pathname design,
but CMUCL solution is not very nice from the standard point of view.

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Raymond Toy
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <4nemrjqhz1.fsf@rtp.ericsson.se>
>>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

    Marco> That is true,... but

    Marco>     Apart from the "path:" search list (derived from my shell
    Marco>     variable) the other search lists can be replaced with a regular
    Marco>     logical pathname, which does not even have to use 'wild inferiors'.

I use search-lists only when building CMUCL.  I have my p86 directory
shadowing my src directory to get the latest p86 stuff without having
a duplicate copy of all of the unchanged stuff in src.

Otherwise, I don't use search-lists.

    Marco> 2 - they are non standard and may interfere with a standard (alas,
    Marco>     implementation dependent) feature of the language. Programs using
    Marco>     logical pathnames may be portable. Programs using the 'path'
    Marco>     search lists feature surely will not.

They do interfere.  Kent Pitman has already explained that the CMUCL
results are ok.  However, if you have a logical-host which matches a
search-list, you lose:  the search-list has precedence.  This could
probably be changed.

    Marco> I am not particularly happy with the whole logical pathname design,
    Marco> but CMUCL solution is not very nice from the standard point of view.

By "CMUCL solution" do you mean search-lists or the implementation of
logical pathnames in CMUCL?

Ray
From: Marco Antoniotti
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <lwiuguo5fj.fsf@copernico.parades.rm.cnr.it>
Raymond Toy <···@rtp.ericsson.se> writes:

> >>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
>     Marco> 2 - they are non standard and may interfere with a standard (alas,
>     Marco>     implementation dependent) feature of the language. Programs using
>     Marco>     logical pathnames may be portable. Programs using the 'path'
>     Marco>     search lists feature surely will not.
> 
> They do interfere.  Kent Pitman has already explained that the CMUCL
> results are ok.  However, if you have a logical-host which matches a
> search-list, you lose:  the search-list has precedence.  This could
> probably be changed.

I do not see any possible way to change this in a completely
satisfactory way.  Giving precedence to logical-pathname resolution
would be an improvement from the point of view of the
standard. (simulating 'wild-inferiors' would probably be worthwhile)

> 
>     Marco> I am not particularly happy with the whole logical pathname design,
>     Marco> but CMUCL solution is not very nice from the standard point of view.
> 
> By "CMUCL solution" do you mean search-lists or the implementation of
> logical pathnames in CMUCL?

I mean search lists.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Raymond Toy
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <4n90hqqbkz.fsf@rtp.ericsson.se>
>>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:

    Marco> Raymond Toy <···@rtp.ericsson.se> writes:

    >> >>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
    Marco> 2 - they are non standard and may interfere with a standard (alas,
    Marco> implementation dependent) feature of the language. Programs using
    Marco> logical pathnames may be portable. Programs using the 'path'
    Marco> search lists feature surely will not.
    >> 
    >> They do interfere.  Kent Pitman has already explained that the CMUCL
    >> results are ok.  However, if you have a logical-host which matches a
    >> search-list, you lose:  the search-list has precedence.  This could
    >> probably be changed.

    Marco> I do not see any possible way to change this in a completely
    Marco> satisfactory way.  Giving precedence to logical-pathname resolution
    Marco> would be an improvement from the point of view of the

I'm mistaken.  In the recent releases, logical pathnames have
precedence over search-lists.  In fact, if you define a logical
pathname with the same host part as the search-list, it's no longer
treated as a search-list---it's a logical pathname.

Ray
From: Marco Antoniotti
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <lwr9vgvk3k.fsf@copernico.parades.rm.cnr.it>
Raymond Toy <···@rtp.ericsson.se> writes:

> >>>>> "Marco" == Marco Antoniotti <·······@copernico.parades.rm.cnr.it> writes:
>     Marco> I do not see any possible way to change this in a completely
>     Marco> satisfactory way.  Giving precedence to logical-pathname resolution
>     Marco> would be an improvement from the point of view of the
> 
> I'm mistaken.  In the recent releases, logical pathnames have
> precedence over search-lists.  In fact, if you define a logical
> pathname with the same host part as the search-list, it's no longer
> treated as a search-list---it's a logical pathname.

Well, I should have checked it myself. :}

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - (0)6 - 68 10 03 16, fax. +39 - (0)6 - 68 80 79 26
http://www.parades.rm.cnr.it
From: Kent M Pitman
Subject: Re: logical pathnames and CMU CL
Date: 
Message-ID: <sfwr9vk3i9y.fsf@world.std.com>
George Smith <············@hockett.phil1.uni-potsdam.de> writes:

> I think I must be misunderstanding something regarding logical
> pathnames. Since some things relating to logical pathnames are
> implementation dependent, it might be worth noting that I am usin CMU
> CL 18a under Solaris 2.5.
> 
> 
> When I try to adapt the simplest example in CLtL2 to unix CMU CL does
> the following:
> 
> * (setf (logical-pathname-translations "foo") 
>       '(("**;*.*.*"          "/lib/prog/")))
> 
> (("**;*.*.*" "/lib/prog/"))
> * (translate-logical-pathname "foo:bar;baz;mum.quux.3")
> 
> #p"/lib/prog/mum.quux.3"
> 
> I would have expected #p"/lib/prog/bar/baz/mum.quux.3"
 
I can't speak to CMU CL, but I can tell you what the standard
says.

The standard says that the behavior is entirely system-dependent.
Ok, well, so much for the standard.

But I can also tell you what the constraint is that drove this.
You can't (meaning "we the CL designers" couldn't) tell what the
operating system would or wouldn't provide in the way of syntax
and semantics of names--so that was a bit of a burden.  

In htis case, for example, not all operating systems provide
"wild inferiors" and CL did not require you to simulate it if
absent.  Let me show you what you would write on a Lisp Machine
file system, just to make it obvious.

 (setf (logical-pathname-translations "FOO")
       '(("**;*.*.*" ">lib>prog>**>*.*.*")))

You'll note two things here.  One is the silly incidental matter
that thought logical pathnames are nominally case-insensitive, 
I prefer uppercase logical host names since uppercase is the
canonical interchange case used in CL; so I gratuitously upcased
"FOO" for reasons unrelated to your problem.  The second is that
Lisp Machine File System (LMFS) syntax has a wild inferiors marker,
and that I've used it to exactly match the source and target.

The late Prof. Bill Martin at MIT, who taught me a lot about
linguistics,  used to remark that the purpose of syntax in 
language is not to say what is obvious, but to say what is not.
If we didn't need to say non-obvious things, then we wouldn't
need refined syntax.  We'd just mash together a lot of terms
and people would guess how they related.   You want to specify
wild inferiors on the right hand side most of the time, just
to preserve your right to not do so the rest of the time.  If
you wrote:

 (setf (logical-pathname-translations "FOO")
       '(("**;*.*.*" ">lib>prog>*.*.*")))

you would map your whole logical tree into a single flat space,
which might in some cases work quite well and would be a real
disaster in others.  But you want the option to gamble in this way.

The problem comes that Unix has no wild inferiors marker,
so you can't do

 (setf (logical-pathname-translations "FOO")
       '(("**;*.*.*" "/lib/prog/**/*")))

unless your vendor specially provides an extended pathname
syntax and magically supports it internally without help from
the operating system.


> The implementation specific example which Steele gives here is:
> 
> (setf (logical-pathname-translations "foo") 
>       '(("**;*.*.*"          "MY-LISPM:>library>foo>**>"))) 
> 
> (translate-logical-pathname "foo:bar;baz;mum.quux.3") 
>    => #P"MY-LISPM:>library>foo>bar>baz>mum.quux.3"
> 

Right.  It's the wild inferiors  that's doing this.

 
> When I try the following, CMU CL does this:
> 
> * (setf (logical-pathname-translations "prog")
>        '(("CODE;*.*.*"             "/lib/prog/")))
> 
> (("CODE;*.*.*" "/lib/prog/"))
> * (translate-logical-pathname "prog:code;documentation.lisp")
> 
> #p"/lib/prog/documentation.lisp"

Right.


> * (translate-logical-pathname
> "prog:code;new-project;documentation.lisp")
> 
> Error in function TRANSLATE-LOGICAL-PATHNAME:
>    No translation for #.(logical-pathname
> "PROG:CODE;NEW-PROJECT;DOCUMENTATION.LISP")
> Restarts:
>   0: [ABORT] Return to Top-Level.
 
You have nod made anything wild, so it maps only one thing--a CODE
dir.  No sibling dirs.  No subdirs.

> 
> I expected #p"/lib/prog/documentation.lisp", but I'm not sure why an
> error is signaled when evaluating:
> 
>    (translate-logical-pathname
> "prog:code;new-project;documentation.lisp")
> 

  Pattern:  Definition:    Seen:      Match?     Expansion

  **;       /lib/prog/     FOO;       Yes      /lib/prog/
  **;       /lib/prog/     BAR;       Yes      /lib/prog/
  **;       /lib/prog/     FOO;BAR;   Yes      /lib/prog/

  FOO;      /lib/prog/     FOO;       Yes      /lib/prog/
  FOO;      /lib/prog/     BAR;       No       ---
  FOO;      /lib/prog/     FOO;BAR;   No       ---

  *;        /lib/prog/     FOO;       Yes      /lib/prog/
  *;        /lib/prog/     BAR;       Yes      /lib/prog/
  *;        /lib/prog/     FOO;BAR;   No       ---

  *;        /lib/*/        FOO;       Yes      /lib/foo/
  *;        /lib/*/        BAR;       Yes      /lib/bar/
  *;        /lib/*/        FOO;BAR;   No       ---

  *;*;      /x/*/x/*/      FOO;       No       ---
  *;*;      /x/*/x/*/      BAR;       No       ---
  *;*;      /x/*/x/*/      FOO;BAR;   Yes      /x/foo/x/bar/

On a file system where wild inferiors are possible (or simulated),
it would be like follows (though such systems may be rare):

  **;       /lib/prog/**/  FOO;       Yes      /lib/prog/foo/
  **;       /lib/prog/**/  BAR;       Yes      /lib/prog/bar/
  **;       /lib/prog/**/  FOO;BAR;   Yes      /lib/prog/foo/bar/

The normal thing I'd do in your case is to figure out a reasonable and
finite number of subdirs to add and then map all of those, as in:

 (setf (logical-pathname-translations "FOO")
       '(("*;*.*.*"     "/lib/prog/*/*")
         ("*;*;*.*.*"   "/lib/prog/*/*/*")
         ("*;*;*;*.*.*" "/lib/prog/*/*/*/*")))

> It seems to me that I get an error whenever I try to use more than one
> directory in a logical pathname. Using more than one directory should
> be possible (cf the following quote from the hyperspec).
> 
> logical-pathname::= [host host-marker]  
>                     [relative-directory-marker] {directory
> directory-marker}*  
>                     [name] [type-marker type [version-marker version]]
> 

You can absolutely do this.  It just doesn't map to anything.  Do not
assume that valid syntax implies valid semantics.  It's not the
parsing of the pathname that is losing for you, it's the attempt to
translate it.

> Can anybody point me to whatever it is that I am misunderstanding? The
> problem I have at hand is rather simple (and frequent): a subtree of a
> file system contains data which I need to access. The root of this
> subtree may need to be moved around from time to time and I want to
> use logical pathnames so that I can specify the root of the tree in
> one place and only modify this one specification when the data is
> moved.

Your problem is not in your understanding of the tree-ness, it's in the
understanding of how to specify the syntax.  Necessarily, this is 
implementation-specific and necessarily the HyperSpec and other portable
doc can only go so far.  Strictly speaking, this is an issue you should
take up with your vendor.  But I can see how you might not have realized
this.  I hope the info I've offered helps you to sort things out from
here.

> 
> Thanks in advance,
> 
> George Smith
> ············@hockett.phil1.uni-potsdam.de
> Institut fuer Germanistik
> Universitaet Potsdam