From: Chez17
Subject: Practical Common Lisp: Need help understanding book code
Date: 
Message-ID: <2933bfb9-fd8d-48cb-bd99-cb9088feebe7@p43g2000hsc.googlegroups.com>
I am going through the book Practical Common Lisp and I have come to a
code segment that I really don't understand, could somebody just take
a look and let me know whats going on?

link: http://www.gigamonkeys.com/book/practical-a-portable-pathname-library.html

(defun pathname-as-directory (name)
  (let ((pathname (pathname name)))
    (when (wild-pathname-p pathname)
      (error "Can't reliably convert wild pathnames."))
    (if (not (directory-pathname-p name))
	(make-pathname
	 :directory (append (or (pathname-directory pathname)
(list :relative))
			    (list (file-namestring)))
	 :name      nil
	 :type      nil
	 :defaults pathname)
	pathname)))

I understand all of the function except for the append after
the :directory (what word would I user here, directory instance?
directory  variable?). I am unsure as to what the 'or' is doing and
what the (list :relative) means. I also am unsure what why it is
appending the file-namestring. Just a brief explanation would be
tremendously helpful.

On a side note, I am very new to usenet groups and I don't even know
if this is an appropriate question to ask. If it isn't, please inform
me and I will cease to ask questions like this.

Thanks so much,
Dave

From: Chez17
Subject: Re: Practical Common Lisp: Need help understanding book code
Date: 
Message-ID: <5fb0d1b1-df14-43d6-99fe-c80e1b3c59ce@o77g2000hsf.googlegroups.com>
On Feb 27, 12:55 pm, Andreas Davour <·······@updateLIKE.uu.HELLse>
wrote:
> Chez17 <······@gmail.com> writes:
> > I am going through the book Practical Common Lisp and I have come to a
> > code segment that I really don't understand, could somebody just take
> > a look and let me know whats going on?
>
> > link:http://www.gigamonkeys.com/book/practical-a-portable-pathname-library...
>
> > (defun pathname-as-directory (name)
> >   (let ((pathname (pathname name)))
> >     (when (wild-pathname-p pathname)
> >       (error "Can't reliably convert wild pathnames."))
> >     (if (not (directory-pathname-p name))
> >    (make-pathname
> >     :directory (append (or (pathname-directory pathname)
> > (list :relative))
> >                        (list (file-namestring)))
> >     :name      nil
> >     :type      nil
> >     :defaults pathname)
> >    pathname)))
>
> > I understand all of the function except for the append after
> > the :directory (what word would I user here, directory instance?
> > directory  variable?). I am unsure as to what the 'or' is doing and
> > what the (list :relative) means. I also am unsure what why it is
> > appending the file-namestring. Just a brief explanation would be
> > tremendously helpful.
>
> What (list :relative) means is only understandable if you know something
> about how a pathname is made. If you know that I think the existence of
> :directory will make sense as well.
>
> Take a look at the hyperspec for the Common Lisp language and you will
> find the documentation for how all the functions work. Start here:http://www.lispworks.com/documentation/HyperSpec/Body/19_.htm
>
> If you have your development environment setup, you can get the relevant
> part of the hyperspec in slime with the touch of a few buttons. It's
> *very* useful. Also, take a look at the MAKE-PATHNAME source in your
> lisp implementation and you might learn a thing or two, after you have
> mastered the basics of the language. Lisp is built in lisp, and that way
> you can learn a lot. Don't forget APROPOS and DESCRIBE either.
>
> The OR is a compact way of doing a conditional. Either of the two things
> OR is given as argument will return something interesting. (OR foo bar)
> will return the evaluated value of 'foo' unless it is nil, then the value
> of 'bar' will be evaluated and returned. If you have not defined the
> symbol 'bar' then it will be an 'undefined symbol' error. Try it.
>
> (let ((foo 17))
>      (or foo bar))
> -> 17
>
> Hope that helped somewhat.
>
> > On a side note, I am very new to usenet groups and I don't even know
> > if this is an appropriate question to ask. If it isn't, please inform
> > me and I will cease to ask questions like this.
>
> This is a very appropriate question to ask.
>
> /Andreas
>
> --
> A: Because it fouls the order in which people normally read text.
> Q: Why is top-posting such a bad thing?
> A: Top-posting.
> Q: What is the most annoying thing on usenet and in e-mail?

Thanks for the response. I think you went a little to basic for what I
was asking. I know what the 'or' operator does, I just don't
understand why we would want to append a blank file-namestring to a
pathame or a list :relative. I should have been more clearer. I
understand WHAT they are doing, I don't understand WHY they are doing
it. So my questions really is why do they do that in this situation?
Sorry for being unclear.
From: Richard M Kreuter
Subject: Re: Practical Common Lisp: Need help understanding book code
Date: 
Message-ID: <87wsoqi4bz.fsf@progn.net>
Chez17 <······@gmail.com> writes:
>> Chez17 <······@gmail.com> writes:

>> > I am going through the book Practical Common Lisp and I have come
>> > to a code segment that I really don't understand, could somebody
>> > just take a look and let me know whats going on?
>>
>> > (defun pathname-as-directory (name)
>> >   (let ((pathname (pathname name)))
>> >     (when (wild-pathname-p pathname)
>> >       (error "Can't reliably convert wild pathnames."))
>> >     (if (not (directory-pathname-p name))
>> >         (make-pathname
>> >          :directory (append (or (pathname-directory pathname)
>> >                                 (list :relative))
>> >                             (list (file-namestring)))
>> >          :name      nil
>> >          :type      nil
>> >          :defaults pathname)
>> >         pathname)))
>>
> I just don't understand why we would want to append a blank
> file-namestring to a pathame or a list :relative. I should have been
> more clearer. I understand WHAT they are doing, I don't understand
> WHY they are doing it. So my questions really is why do they do that
> in this situation?

Under Unix and Windows (but not all file systems people have used Lisp
with), directories share the same namespace as files, and so you can
refer to any directory in at least two ways: "/tmp" and "/tmp/", for
example.  Now, the CL pathnames system has operations that "fill in"
the "missing" fields in filenames, and these operations honor the
structure of their arguments.  For example, you'll probably see the
following under most implementations:

  (merge-pathnames "foo.lisp" "/tmp")
  => #P"/foo.lisp"

  (merge-pathnames "foo.lisp" "/tmp/")
  => #P"/tmp/foo.lisp"

What's going on here is that the structural difference between the
pathname parsed from "/tmp" and the pathname parsed from "/tmp/" leads
to observable differences with various pathname
operations. Consequently it's occasionally necessary to represent a
filename "as a directory", i.e., the pathname that you'd get from a
parse of the namestring ending with the slash, above.  That's what
a function like PATHNAME-AS-DIRECTORY is for.

--
RmK
From: Pascal J. Bourguignon
Subject: Re: Practical Common Lisp: Need help understanding book code
Date: 
Message-ID: <7c7igpz7cv.fsf@pbourguignon.anevia.com>
Chez17 <······@gmail.com> writes:

> On Feb 27, 12:55 pm, Andreas Davour <·······@updateLIKE.uu.HELLse>
> wrote:
>> Chez17 <······@gmail.com> writes:
>> > I am going through the book Practical Common Lisp and I have come to a
>> > code segment that I really don't understand, could somebody just take
>> > a look and let me know whats going on?
>>
>> > link:http://www.gigamonkeys.com/book/practical-a-portable-pathname-library...
>>
>> > (defun pathname-as-directory (name)
>> >   (let ((pathname (pathname name)))
>> >     (when (wild-pathname-p pathname)
>> >       (error "Can't reliably convert wild pathnames."))
>> >     (if (not (directory-pathname-p name))
>> >    (make-pathname
>> >     :directory (append (or (pathname-directory pathname)
>> > (list :relative))
>> >                        (list (file-namestring)))
>> >     :name      nil
>> >     :type      nil
>> >     :defaults pathname)
>> >    pathname)))
>>
>> > I understand all of the function except for the append after
>> > the :directory (what word would I user here, directory instance?
>> > directory  variable?). I am unsure as to what the 'or' is doing and
>> > what the (list :relative) means. I also am unsure what why it is
>> > appending the file-namestring. Just a brief explanation would be
>> > tremendously helpful.
>>
>> What (list :relative) means is only understandable if you know something
>> about how a pathname is made. If you know that I think the existence of
>> :directory will make sense as well.
>> [...]
>
> Thanks for the response. I think you went a little to basic for what I
> was asking. I know what the 'or' operator does, I just don't
> understand why we would want to append a blank file-namestring to a
> pathame or a list :relative. I should have been more clearer. I
> understand WHAT they are doing, I don't understand WHY they are doing
> it. So my questions really is why do they do that in this situation?
> Sorry for being unclear.

:directory is a keyword.  The directory argument of make-pathname
allows you to specify the directory part of the pathname.  As Richard
explains, CL pathnames distinguish the directories from the files
(since this distinction exists on some systems).

This function wants to convert a pathname to a file named X to a
pathname to a directory named X.  On a unix system, the physical
pathname would be the same, no difference, but on some other system,
you could have both a file and a directory named X.

Now this function is still useful on unix systems, because the various
CL implementation will behave differently on unix system. For example
(DIRECTORY "/*") will return only files on some implementation, or
both files and directories, but as file names, on other implementions.
In the later case, we want to convert back the file pathname to
directory pathname, only for directories of course.

(directory "/*") --> ("/bin" "/etc" "/home" "/usr" "/some-random-file")

(Since directories are files on unix, this is acceptable, from the
unix point of view).

But in CL, we want to convert "/bin" to "/bin/", that is, 
convert (make-pathname :directory '(:absolute) :name "bin" :type nil)
to      (make-pathname :directory '(:absolute "bin") :name nil :type nil)



-- 
__Pascal Bourguignon__
From: Chez17
Subject: Re: Practical Common Lisp: Need help understanding book code
Date: 
Message-ID: <3c93556f-3108-4d5f-a527-08ad51922a29@o77g2000hsf.googlegroups.com>
I think I get it now. Thanks so much for all your help and insight.