unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* locate-file in Emacs
@ 2002-04-17  5:05 Hrvoje Niksic
  2002-04-17  5:47 ` Eli Zaretskii
  2002-04-17  9:28 ` Stefan Monnier
  0 siblings, 2 replies; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-17  5:05 UTC (permalink / raw)


Several years ago I talked to Richard Stallman about incorporating the
`locate-file' function in Emacs.  `locate-file' is a very useful
XEmacs function that searches for a file in a path.

For example, to find an elisp file in load-path, one would use this:

    (locate-file "simple" load-path '(".elc" ".el"))
      => "/usr/local/lib/xemacs-21.4.6/lisp/simple.elc"

Or, to locate a Unix executable:

    (locate-file "ls" (split-string (getenv "PATH") path-separator)
                 nil 'executable)
      => "/bin/ls"

To make the same code work under Windows:

    (locate-file "links" (split-string (getenv "PATH") path-separator)
                 '("" ".exe") 'executable)
      => "/usr/bin/links"

I find that there are many uses for this kind of lookup across a list
of directories, and I would like to be able to use this function in
portable elisp programs.  The XEmacs version is written in C with
(probably) unclear copyright status, but Richard agreed to include a
Lisp version of the function.  I came back to that yesterday and wrote
one.

The code follows below.  Please let me know what you think.


(defun locate-file (filename path-list &optional suffixes mode)
  "Search for FILENAME through PATH-LIST.

If SUFFIXES is non-nil, it should be a list of suffixes to append to
file name when searching.

If MODE is non-nil, it should be a symbol or a list of symbols representing
requirements.  Allowed symbols are `exists', `executable', `writable', and
`readable'.  If MODE is nil, it defaults to `readable'."
  (let (all-file-names all-mode-functions)
    ;; Create a list of strings of FILENAME+suffix for each of
    ;; SUFFIXES, so we don't have to do it (and cons a new string)
    ;; once for each directory.
    (setq all-file-names
	  (if suffixes
	      (mapcar (lambda (suffix)
			(concat filename suffix))
		      suffixes)
	    (list filename)))

    ;; Convert MODE into a list of tests all of which need to return t
    ;; for a file to pass.
    (if (null mode)
	(setq all-mode-functions '(file-readable-p))
      (when (symbolp mode)
	(setq mode (list mode)))
      (setq all-mode-functions
	    (mapcar
	     (lambda (m)
	       (cond ((eq m 'exists)
		      'file-exists-p)
		     ((eq m 'executable)
		      'file-executable-p)
		     ((eq m 'writable)
		      ;; file-writable-p returns t if the dir is
		      ;; writable and the file doesn't exist.
		      (lambda (f)
			(and (file-exists-p f)
			     (file-writable-p f))))
		     ((eq m 'readable)
		      'file-readable-p)
		     (t
		      (error "Invalid mode: %s" m))))
	     mode)))

    (catch 'found
      (dolist (directory path-list)
	(dolist (file all-file-names)
	  (let ((full-name (expand-file-name file directory))
		(mode-functions all-mode-functions))
	    (while (and mode-functions
			(funcall (car mode-functions) full-name))
	      (pop mode-functions))
	    (when (null mode-functions)
	      ;; All functions passed -- we found the one.
	      (throw 'found full-name)))))
      nil)))

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17  5:05 locate-file in Emacs Hrvoje Niksic
@ 2002-04-17  5:47 ` Eli Zaretskii
  2002-04-17  8:53   ` Hrvoje Niksic
  2002-04-17  9:28 ` Stefan Monnier
  1 sibling, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2002-04-17  5:47 UTC (permalink / raw)
  Cc: emacs-devel

> From: Hrvoje Niksic <hniksic@arsdigita.com>
> Date: Wed, 17 Apr 2002 07:05:26 +0200
> 
> For example, to find an elisp file in load-path, one would use this:
> 
>     (locate-file "simple" load-path '(".elc" ".el"))
>       => "/usr/local/lib/xemacs-21.4.6/lisp/simple.elc"
> 
> Or, to locate a Unix executable:
> 
>     (locate-file "ls" (split-string (getenv "PATH") path-separator)
>                  nil 'executable)
>       => "/bin/ls"
> 
> To make the same code work under Windows:
> 
>     (locate-file "links" (split-string (getenv "PATH") path-separator)
>                  '("" ".exe") 'executable)
>       => "/usr/bin/links"
> 
> I find that there are many uses for this kind of lookup across a list
> of directories, and I would like to be able to use this function in
> portable elisp programs.  The XEmacs version is written in C with
> (probably) unclear copyright status, but Richard agreed to include a
> Lisp version of the function.  I came back to that yesterday and wrote
> one.
> 
> The code follows below.  Please let me know what you think.

I'm not saying that we already have this functionality (I didn't
check that), but I thought I'd mention similar functionality:

  - executable-find in executable.el

  - find-lisp.el

  - the openp function (implemented in C) which can be used as a base
    for either a C primitive or a Lisp function (it is currently used
    by `load').

I do agree that the feature you suggest is a useful one.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17  5:47 ` Eli Zaretskii
@ 2002-04-17  8:53   ` Hrvoje Niksic
  0 siblings, 0 replies; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-17  8:53 UTC (permalink / raw)
  Cc: emacs-devel

"Eli Zaretskii" <eliz@is.elta.co.il> writes:

> I'm not saying that we already have this functionality (I didn't
> check that), but I thought I'd mention similar functionality:
>
>   - executable-find in executable.el
>
>   - find-lisp.el

Yes, `locate-file' may be seen as a generalization of these, also
useful in other contexts.  (E.g. finding data files, java classes,
whatever.)

>   - the openp function (implemented in C) which can be used as a
>     base for either a C primitive or a Lisp function (it is
>     currently used by `load').

locate-file is used internally by XEmacs in ways similar to openp, but
I think the interface is nice, regardless of how it is implemented.
For instance, if you think the Lisp version is slow, or requires
caching, etc., that can be added without breaking the interface.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17  5:05 locate-file in Emacs Hrvoje Niksic
  2002-04-17  5:47 ` Eli Zaretskii
@ 2002-04-17  9:28 ` Stefan Monnier
  2002-04-17  9:47   ` Hrvoje Niksic
  1 sibling, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-04-17  9:28 UTC (permalink / raw)
  Cc: emacs-devel

> Several years ago I talked to Richard Stallman about incorporating the
> `locate-file' function in Emacs.  `locate-file' is a very useful
> XEmacs function that searches for a file in a path.

I like it.
This is obviously very convenient.  It should ideally be
implemented on top of the `openp' function, such as the
quick-hack implementation below.

How important is the MODE argument ?
I would much prefer to have a PREDICATE argument instead (easier
to implement and more flexible).  Also the current `openp' code
already checks for `file-readable-p' and `not file-directory-p'
rather than just file-readable-p.


	Stefan


DEFUN ("locate-file", Flocate_file, Slocate_file, 2, 4, 0,
       doc: /* Search for FILENAME through PATH.

If SUFFIXES is non-nil, it should be a list of suffixes to append to
file name when searching.

If MODE is non-nil, it should be a symbol or a list of symbols representing
requirements.  Allowed symbols are `exists', `executable', `writable', and
`readable'.  If MODE is nil, it defaults to `readable'.  */)
     (filename, path, suffixes, mode)
     Lisp_Object filename, path_list, suffixes, mode;
{
  Lisp_Object file;
  /* FIXME: implement the `mode' functionality.  */
  int fd = openp (path, filename, suffixes, &file, 0);
  if (fd > 0)
    close (fd);
  return file;
}

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17  9:28 ` Stefan Monnier
@ 2002-04-17  9:47   ` Hrvoje Niksic
  2002-04-17 10:01     ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-17  9:47 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> Several years ago I talked to Richard Stallman about incorporating the
>> `locate-file' function in Emacs.  `locate-file' is a very useful
>> XEmacs function that searches for a file in a path.
>
> I like it.

Thanks.

> This is obviously very convenient.  It should ideally be implemented
> on top of the `openp' function, such as the quick-hack
> implementation below.

It ignores a part of the interface -- the MODE argument in this case.
My version may not be as optimized, but at least it implements all of
the interface.  You might want to start by including (and advertising)
it, and replacing it with an optimized version if it gets used.

PREDICATE might make sense, but I don't remember needing it in
practice.  Plus, it'd change the interface and hence undermine the
whole point of sharing the function.

Note that MODE is actually quite easy to implement -- just add a MODE
option to openp(), and have it call access() instead of open() when
MODE is provided.  Before doing anything else, decode MODE from Lisp
to C with code like this (written by me, thus copyright-safe):

static int
decode_mode_1 (Lisp_Object mode)
{
  if (EQ (mode, Qexists))
    return F_OK;
  else if (EQ (mode, Qexecutable))
    return X_OK;
  else if (EQ (mode, Qwritable))
    return W_OK;
  else if (EQ (mode, Qreadable))
    return R_OK;
  else if (INTP (mode))
    {
      check_int_range (XINT (mode), 0, 7);
      return XINT (mode);
    }
  else
    signal_simple_error ("Invalid value", mode);
  return 0;			/* unreached */
}

static int
decode_mode (Lisp_Object mode)
{
  if (NILP (mode))
    return R_OK;
  else if (CONSP (mode))
    {
      Lisp_Object tail;
      int mask = 0;
      EXTERNAL_LIST_LOOP (tail, mode)
	mask |= decode_mode_1 (XCAR (tail));
      return mask;
    }
  else
    return decode_mode_1 (mode);
}

Such decoded mode is a valid second argument to access.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17  9:47   ` Hrvoje Niksic
@ 2002-04-17 10:01     ` Stefan Monnier
  2002-04-18 13:16       ` Hrvoje Niksic
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-04-17 10:01 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

> > This is obviously very convenient.  It should ideally be implemented
> > on top of the `openp' function, such as the quick-hack
> > implementation below.
> 
> It ignores a part of the interface -- the MODE argument in this case.
> My version may not be as optimized, but at least it implements all of
> the interface.  You might want to start by including (and advertising)
> it, and replacing it with an optimized version if it gets used.

Yes, I understand that.  I'm interested in figuring out whether this
interface is really what we want to advertise.

> PREDICATE might make sense, but I don't remember needing it in
> practice.  Plus, it'd change the interface and hence undermine the
> whole point of sharing the function.

Well, I was wondering if it was possible to get XEmacs to adopt it
as well ;-)

> Note that MODE is actually quite easy to implement -- just add a MODE
> option to openp(), and have it call access() instead of open() when
> MODE is provided.  Before doing anything else, decode MODE from Lisp

Sure.  But you also need to add the implementation of `access'
on top of magic-file-handlers, ...
Whereas PREDICATE would just be a 2 liner.

I like code to stay simple and short, and it's even better if it's
flexible, so I really like the PREDICATE argument much better.

I think that if XEmacs agrees that MODE should really be PREDICATE
(it's pretty easy to support both types of args at the same time),
the "eventual compatibility" we'd then get should be "good enough".


	Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-17 10:01     ` Stefan Monnier
@ 2002-04-18 13:16       ` Hrvoje Niksic
  2002-04-18 13:54         ` Miles Bader
  2002-04-18 14:08         ` Stefan Monnier
  0 siblings, 2 replies; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 13:16 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> PREDICATE might make sense, but I don't remember needing it in
>> practice.  Plus, it'd change the interface and hence undermine the
>> whole point of sharing the function.
>
> Well, I was wondering if it was possible to get XEmacs to adopt it
> as well ;-)

That would break backward compatibility, which is fairly important in
this case because I've already changed the interface once.  (But I've
kept the compatibility with the old interface.)

I've fixed the function to always check for non-directoriness, which
the XEmacs version does, too.  Please let me know if you include the
function (which Richard promised to do, but that was some time ago):

(defun locate-file (filename path-list &optional suffixes mode)
  "Search for FILENAME through PATH-LIST.

If SUFFIXES is non-nil, it should be a list of suffixes to append to
file name when searching.

If MODE is non-nil, it should be a symbol or a list of symbols representing
requirements.  Allowed symbols are `exists', `executable', `writable', and
`readable'.  If MODE is nil, it defaults to `readable'."
  (let (all-file-names all-mode-functions)
    ;; Create a list of strings of FILENAME+suffix for each of
    ;; SUFFIXES, so we don't have to do it (and cons a new string)
    ;; once for each directory.
    (setq all-file-names
	  (if suffixes
	      (mapcar (lambda (suffix)
			(concat filename suffix))
		      suffixes)
	    (list filename)))

    ;; Convert MODE into a list of tests all of which need to return t
    ;; for a file to pass.
    (if (null mode)
	(setq all-mode-functions '(file-readable-p))
      (when (symbolp mode)
	(setq mode (list mode)))
      (setq all-mode-functions
	    (mapcar
	     (lambda (m)
	       (cond ((eq m 'exists)
		      'file-exists-p)
		     ((eq m 'executable)
		      'file-executable-p)
		     ((eq m 'writable)
		      ;; file-writable-p returns t if the dir is
		      ;; writable and the file doesn't exist.
		      (lambda (f)
			(and (file-exists-p f)
			     (file-writable-p f))))
		     ((eq m 'readable)
		      'file-readable-p)
		     (t
		      (error "Invalid mode: %s" m))))
	     mode)))

    (catch 'found
      (dolist (directory path-list)
	(dolist (file all-file-names)
	  (let ((full-name (expand-file-name file directory))
		(mode-functions all-mode-functions))
	    (when (not (file-directory-p full-name))
	      (while (and mode-functions
			  (funcall (car mode-functions) full-name))
		(pop mode-functions))
	      (when (null mode-functions)
		;; All functions passed -- we found the one.
		(throw 'found full-name))))))
      nil)))

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 13:16       ` Hrvoje Niksic
@ 2002-04-18 13:54         ` Miles Bader
  2002-04-18 14:09           ` Hrvoje Niksic
  2002-04-18 14:08         ` Stefan Monnier
  1 sibling, 1 reply; 31+ messages in thread
From: Miles Bader @ 2002-04-18 13:54 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Hrvoje Niksic <hniksic@arsdigita.com> writes:
> > Well, I was wondering if it was possible to get XEmacs to adopt it
> > as well ;-)
> 
> That would break backward compatibility, which is fairly important in
> this case because I've already changed the interface once.  (But I've
> kept the compatibility with the old interface.)

Why would this matter?  All existing user code would continue to work,
and if an independent package author wanted to maintain compatibility
with old versions of xemacs, he could just not use the new feature...
[Clearly all internal code can do whatever it wants.]

-Miles
-- 
Love is a snowmobile racing across the tundra.  Suddenly it flips over,
pinning you underneath.  At night the ice weasels come.  --Nietzsche

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 13:16       ` Hrvoje Niksic
  2002-04-18 13:54         ` Miles Bader
@ 2002-04-18 14:08         ` Stefan Monnier
  2002-04-18 15:11           ` Hrvoje Niksic
  1 sibling, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-04-18 14:08 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

> "Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:
> 
> >> PREDICATE might make sense, but I don't remember needing it in
> >> practice.  Plus, it'd change the interface and hence undermine the
> >> whole point of sharing the function.
> >
> > Well, I was wondering if it was possible to get XEmacs to adopt it
> > as well ;-)
> 
> That would break backward compatibility, which is fairly important in

I fail to see why:

	(defun locate-file (f p s predicate)
	  (cond
	   ((memq predicate '(executable writable ...)) ...)
	   ((functionp predicate) nil)
	   ((listp predicate) ...)
	  ...)

you should be able to keep backward compatibility just fine.
The qusetion is whether or not you find the `predicate' interface
preferable.  I do because it's more flexible.
But I'm biased since it also makes our implementation simpler.

Of course, otherwise we can export the `openp' function "raw"
(but adding a `predicate' argument) and then implement locate-file's
MODE argument in elisp on top of it.

I think there's no question that locate-file should exist in Emacs
and I thank you for pushing us to implement it.


	Stefan

PS: a grep through XEmacs packages seems to indicate that the MODE argument
    is rarely used and that the few times it's used it's only to check
    executablility but uses the integer 1 instead of the `executable'
    symbol.  So assuming that the core code is updated to the new interface,
    I'm not even sure if `executable', `writable' and friends needs to
    be supported (although the integer 1 should be).
    Unless of course I missed something.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 13:54         ` Miles Bader
@ 2002-04-18 14:09           ` Hrvoje Niksic
  2002-04-18 14:25             ` Miles Bader
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 14:09 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Miles Bader <miles@gnu.org> writes:

> Hrvoje Niksic <hniksic@arsdigita.com> writes:
>> > Well, I was wondering if it was possible to get XEmacs to adopt it
>> > as well ;-)
>> 
>> That would break backward compatibility, which is fairly important in
>> this case because I've already changed the interface once.  (But I've
>> kept the compatibility with the old interface.)
>
> Why would this matter?  All existing user code would continue to
> work

How, if backward compatibility were broken?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 14:09           ` Hrvoje Niksic
@ 2002-04-18 14:25             ` Miles Bader
  0 siblings, 0 replies; 31+ messages in thread
From: Miles Bader @ 2002-04-18 14:25 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Hrvoje Niksic <hniksic@arsdigita.com> writes:
> > Why would this matter?  All existing user code would continue to
> > work
> 
> How, if backward compatibility were broken?

Because (as far as I can see) Stefan proposed _adding_ a new
interpretation of one of the existing arguments, in a way that would
continue to allow the old usage.  The argument currently used for `mode'
would be extended to allow predicates as well, and the overlap between a
`predicate' and the existing allowable values for that argument is
small, and non-problematic in practice, I think.

-Miles

-- 
Come now, if we were really planning to harm you, would we be waiting here, 
 beside the path, in the very darkest part of the forest?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 14:08         ` Stefan Monnier
@ 2002-04-18 15:11           ` Hrvoje Niksic
  2002-04-18 15:27             ` Stefan Monnier
  2002-04-18 15:31             ` Miles Bader
  0 siblings, 2 replies; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 15:11 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> That would break backward compatibility, which is fairly important in
>
> I fail to see why:
>
> 	(defun locate-file (f p s predicate)
> 	  (cond
> 	   ((memq predicate '(executable writable ...)) ...)

That's fine; I thought you wanted to disallow old-style MODE in favor
of PREDICATE which you found easier to implement.

> you should be able to keep backward compatibility just fine.
> The qusetion is whether or not you find the `predicate' interface
> preferable.

I find this "mixing" of interfaces far from elegant, but I'll agree
that it's flexible.  If that's your price of keeping a unified
interface, I'll accept.  But I'd prefer to just keep MODE.

> PS: a grep through XEmacs packages seems to indicate that the MODE
>     argument is rarely used and that the few times it's used it's
>     only to check executablility but uses the integer 1 instead of
>     the `executable' symbol.

That's the old interface, which XEmacs still supports.  In it the MODE
was a number equivalent to what access() accepts as the second arg,
and the SUFFIXES were one colon-separated string.

But I don't require GNU Emacs to support this old interface.

>     So assuming that the core code is updated to the new interface,
>     I'm not even sure if `executable', `writable' and friends needs
>     to be supported

Then you don't care about the compatibility with the existing XEmacs
interface.  I can understand that, because you don't have to support
its uses; but I do.  If it means something to you as a "proof", I've
used it in my programs.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:11           ` Hrvoje Niksic
@ 2002-04-18 15:27             ` Stefan Monnier
  2002-04-18 16:20               ` Hrvoje Niksic
                                 ` (2 more replies)
  2002-04-18 15:31             ` Miles Bader
  1 sibling, 3 replies; 31+ messages in thread
From: Stefan Monnier @ 2002-04-18 15:27 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

> >> That would break backward compatibility, which is fairly important in
> >
> > I fail to see why:
> >
> > 	(defun locate-file (f p s predicate)
> > 	  (cond
> > 	   ((memq predicate '(executable writable ...)) ...)
> 
> That's fine; I thought you wanted to disallow old-style MODE in favor
> of PREDICATE which you found easier to implement.

No, I'm quite aware of the fact that breaking backward compatibility
is not done so lightly ;-).

> > you should be able to keep backward compatibility just fine.
> > The question is whether or not you find the `predicate' interface
> > preferable.
> 
> I find this "mixing" of interfaces far from elegant, but I'll agree
> that it's flexible.

I'd of course document the MODE-style arguments as obsolete, so
that the inelegance is "temporary".

> > PS: a grep through XEmacs packages seems to indicate that the MODE
> >     argument is rarely used and that the few times it's used it's
> >     only to check executablility but uses the integer 1 instead of
> >     the `executable' symbol.
> 
> That's the old interface, which XEmacs still supports.  In it the MODE
> was a number equivalent to what access() accepts as the second arg,
> and the SUFFIXES were one colon-separated string.

That's what I figured.

> >     So assuming that the core code is updated to the new interface,
> >     I'm not even sure if `executable', `writable' and friends needs
> >     to be supported
> 
> Then you don't care about the compatibility with the existing XEmacs
> interface.  I can understand that, because you don't have to support
> its uses; but I do.  If it means something to you as a "proof", I've
> used it in my programs.

I have no doubt that it's been used, so do you happen to know if it
has been used in packages that are in active use ?

Based on the information here, I think I'll go ahead and implement
the functionality on top of `openp' with just a `predicate' argument
and without backward compatibility for `mode'.

But I have one question left: should the `file-directory-p' check be enforced
independently from `predicate' ?
I.e. can (locate-file f p s 'file-readable-p) return a directory ?

"Yes" is better since it allows the caller to choose whether directories
are considered or not but "no" is better because it allows
(locate-file file path suffixes 'file-executable-p) to behave like
your current (locate-file file path suffixes 'executable).
Or does the current XEmacs code always consider directories anyway ?


	Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:11           ` Hrvoje Niksic
  2002-04-18 15:27             ` Stefan Monnier
@ 2002-04-18 15:31             ` Miles Bader
  2002-04-18 16:29               ` Hrvoje Niksic
  1 sibling, 1 reply; 31+ messages in thread
From: Miles Bader @ 2002-04-18 15:31 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Hrvoje Niksic <hniksic@arsdigita.com> writes:
> > you should be able to keep backward compatibility just fine.
> > The qusetion is whether or not you find the `predicate' interface
> > preferable.
> 
> I find this "mixing" of interfaces far from elegant, but I'll agree
> that it's flexible.  If that's your price of keeping a unified
> interface, I'll accept.  But I'd prefer to just keep MODE.

I think that probably the best thing to do is to simply deprecate the
MODE interface in documentation and recommend using a predicate in both
emacs and xemacs.  So think of it as an interface _change_, but with
backward compatibility (similar to the previous interface change you
apparently made).

My reasoning:

  * Clearly a predicate is more powerful, and could completely replace
    the MODE interface if it weren't for backward compatibility concerns.

  * According to Stefan's earlier post, he couldn't find any code that
    actually used any value for MODE except `executable', so the
    potential programmer-convenience benefit of the MODE interface
    doesn't appear to be much of an issue
    [e.g. being able to say '(writable executable) instead of
     (lambda (f) (or (file-writable-p f) (file-executable-p f))) ]

  * Using a predicate is more elegant, and more `lispy'.

I understand that it's annoying to make yet another interface to the
same function, but this one is pretty innocuous.

-Miles
-- 
Quidquid latine dictum sit, altum viditur.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:27             ` Stefan Monnier
@ 2002-04-18 16:20               ` Hrvoje Niksic
  2002-04-18 18:59                 ` Stefan Monnier
  2002-04-18 16:39               ` Eli Zaretskii
  2002-04-19  5:25               ` Richard Stallman
  2 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 16:20 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> > you should be able to keep backward compatibility just fine.
>> > The question is whether or not you find the `predicate' interface
>> > preferable.
>> 
>> I find this "mixing" of interfaces far from elegant, but I'll agree
>> that it's flexible.
>
> I'd of course document the MODE-style arguments as obsolete, so that
> the inelegance is "temporary".

I don't agree with that.  At least, I wouldn't obsolete them for
XEmacs.  I think they're quite useful, and much faster than the
generic PREDICATE.

> I have no doubt that it's been used, so do you happen to know if it
> has been used in packages that are in active use ?

I have no statistics about that.

> Based on the information here, I think I'll go ahead and implement
> the functionality on top of `openp' with just a `predicate' argument
> and without backward compatibility for `mode'.

Please name your function differently to avoid confusion.  I am
beginning to regret bringing this up.

> But I have one question left: should the `file-directory-p' check be enforced
> independently from `predicate' ?

Yes, please.  For several days I ran my `locate-file' in place of
XEmacs's original (to shake out the bugs), and I noticed that
`sh-script' wouldn't load.  That is because my locate-file found
contains "packages/sh-script" (a directory) before
"packages/sh-script/lisp/sh-script[.elc]" (a file).

> I.e. can (locate-file f p s 'file-readable-p) return a directory ?
>
> "Yes" is better since it allows the caller to choose whether
> directories are considered or not but "no" is better because it
> allows (locate-file file path suffixes 'file-executable-p) to behave
> like your current (locate-file file path suffixes 'executable).  Or
> does the current XEmacs code always consider directories anyway ?

I think it is ok for a function named `locate-file' to ignore
directories.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 16:39               ` Eli Zaretskii
@ 2002-04-18 16:24                 ` Hrvoje Niksic
  0 siblings, 0 replies; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 16:24 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Eli Zaretskii <eliz@is.elta.co.il> writes:

> On Thu, 18 Apr 2002, Stefan Monnier wrote:
>
>> But I have one question left: should the `file-directory-p' check be enforced
>> independently from `predicate' ?
>> I.e. can (locate-file f p s 'file-readable-p) return a directory ?
>
> My vote is for NO, for a couple of reasons:
>
>   - it is rare for a program to want to find files and directories alike, 
>     so using file-directory-p is not a nuisance, in practice;
>
>   - different filesystems impose different limitations on what system 
>     calls work on directories (for example, some won't let you `read' a 
>     directory), so the application will have to filter non-files anyway.
>
> Of course, compatibility considerations could render these reasons less 
> important.

Fortunately, compatibility agrees with your reasoning, and so do I.

Note that XEmacs's internal locate_file() is based on what was once
openp().  So the similarities are not completely coincidental.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:31             ` Miles Bader
@ 2002-04-18 16:29               ` Hrvoje Niksic
  2002-04-18 16:45                 ` Miles Bader
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 16:29 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Miles Bader <miles@gnu.org> writes:

> I think that probably the best thing to do is to simply deprecate
> the MODE interface

You find it best, but I don't agree.  I think MODE is nice for the
added efficiency (which my implementation doesn't use).  I've never
needed a generic PREDICATE argument, but I did use MODE.

Another thing I don't like about that change is that it mixes the
namespaces -- PREDICATE would silently misbehave work if your function
happens to be named `executable' or `readable'.  It may not be a
problem in practice, but I'd prefer to keep the namespaces separate.

>   * Using a predicate is more elegant, and more `lispy'.

Maybe we should revert to using OR-ed numbers.  :-)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:27             ` Stefan Monnier
  2002-04-18 16:20               ` Hrvoje Niksic
@ 2002-04-18 16:39               ` Eli Zaretskii
  2002-04-18 16:24                 ` Hrvoje Niksic
  2002-04-19  5:25               ` Richard Stallman
  2 siblings, 1 reply; 31+ messages in thread
From: Eli Zaretskii @ 2002-04-18 16:39 UTC (permalink / raw)
  Cc: Hrvoje Niksic, emacs-devel


On Thu, 18 Apr 2002, Stefan Monnier wrote:

> But I have one question left: should the `file-directory-p' check be enforced
> independently from `predicate' ?
> I.e. can (locate-file f p s 'file-readable-p) return a directory ?

My vote is for NO, for a couple of reasons:

  - it is rare for a program to want to find files and directories alike, 
    so using file-directory-p is not a nuisance, in practice;

  - different filesystems impose different limitations on what system 
    calls work on directories (for example, some won't let you `read' a 
    directory), so the application will have to filter non-files anyway.

Of course, compatibility considerations could render these reasons less 
important.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 16:29               ` Hrvoje Niksic
@ 2002-04-18 16:45                 ` Miles Bader
  2002-04-18 16:49                   ` Hrvoje Niksic
  0 siblings, 1 reply; 31+ messages in thread
From: Miles Bader @ 2002-04-18 16:45 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Hrvoje Niksic <hniksic@arsdigita.com> writes:
> > I think that probably the best thing to do is to simply deprecate
> > the MODE interface
> 
> You find it best, but I don't agree.  I think MODE is nice for the
> added efficiency (which my implementation doesn't use).

I think that the common cases could (and probably should) be hardwired
for efficiency's sake.  [E.g., (eq predicate 'file-executable-p) ]

> Another thing I don't like about that change is that it mixes the
> namespaces -- PREDICATE would silently misbehave work if your function
> happens to be named `executable' or `readable'.

[I suspect that even in _that_ case, it's pretty likely that
 a function called `executable' in fact just does `file-executable-p',
 so it would _still_ work...  spooooky ... :-) ]

-Miles

-- 
I have seen the enemy, and he is us.  -- Pogo

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 16:45                 ` Miles Bader
@ 2002-04-18 16:49                   ` Hrvoje Niksic
  2002-04-18 16:54                     ` Miles Bader
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-18 16:49 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Miles Bader <miles@gnu.org> writes:

> Hrvoje Niksic <hniksic@arsdigita.com> writes:
>> > I think that probably the best thing to do is to simply deprecate
>> > the MODE interface
>> 
>> You find it best, but I don't agree.  I think MODE is nice for the
>> added efficiency (which my implementation doesn't use).
>
> I think that the common cases could (and probably should) be hardwired
> for efficiency's sake.  [E.g., (eq predicate 'file-executable-p) ]

Maybe.  But playing that kind of game can be extremely dangerous.
People can and do redefine built-in functions for all kinds of
reasons.  When I say `file-executable-p', I expect *that* to be run,
and not something else.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 16:49                   ` Hrvoje Niksic
@ 2002-04-18 16:54                     ` Miles Bader
  0 siblings, 0 replies; 31+ messages in thread
From: Miles Bader @ 2002-04-18 16:54 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

Hrvoje Niksic <hniksic@arsdigita.com> writes:
> > I think that the common cases could (and probably should) be hardwired
> > for efficiency's sake.  [E.g., (eq predicate 'file-executable-p) ]
> 
> Maybe.  But playing that kind of game can be extremely dangerous.
> People can and do redefine built-in functions for all kinds of reasons.
> When I say `file-executable-p', I expect *that* to be run, and not
> something else.

Ok, then use

   (eq (symbol-function predicate) #<subr Ffile_executable_p>)

replacing #<subr Ffile_executable_p> with appropriate magic.

-Miles
-- 
"I distrust a research person who is always obviously busy on a task."
   --Robert Frosch, VP, GM Research

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 16:20               ` Hrvoje Niksic
@ 2002-04-18 18:59                 ` Stefan Monnier
  2002-04-25 12:12                   ` Hrvoje Niksic
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-04-18 18:59 UTC (permalink / raw)
  Cc: Stefan Monnier, emacs-devel

> I don't agree with that.  At least, I wouldn't obsolete them for
> XEmacs.  I think they're quite useful, and much faster than the
> generic PREDICATE.

The useful part is not relevant: `executable' is not much better
than `file-executable-p' for people writing code.

Now the performance issue is something new that I haven't
thought about too much.  The only case where it matters seems to be
when predicate is `file-executable-p' (since it seems to be the
only MODE in use that I can see, apart from the default).

How significant is it ?  I truly do not know.

> > I have no doubt that it's been used, so do you happen to know if it
> > has been used in packages that are in active use ?
> I have no statistics about that.

Anectodes, maybe ?
When I said active use, I meant a package that can be downloaded from the
web as opposed to someone's .emacs file.  Whether it's used by a million
people or just by 5 doesn't matter too much at this stage.

> > Based on the information here, I think I'll go ahead and implement
> > the functionality on top of `openp' with just a `predicate' argument
> > and without backward compatibility for `mode'.
> 
> Please name your function differently to avoid confusion.  I am
> beginning to regret bringing this up.

No, it would be silly not to have compatible interfaces.

[ Note that my current implementation accepts `1' as predicate to
mean file-executable-p (more or less, since it uses the `access'
syscall, so it's actually as fast as the previous code and more
importantly behaves the same). ]

> > But I have one question left: should the `file-directory-p' check be enforced
> > independently from `predicate' ?
> 
> Yes, please.  For several days I ran my `locate-file' in place of
> XEmacs's original (to shake out the bugs), and I noticed that
> `sh-script' wouldn't load.  That is because my locate-file found
> contains "packages/sh-script" (a directory) before
> "packages/sh-script/lisp/sh-script[.elc]" (a file).

I didn't mean to change the existing behavior, but I meant "when a predicate
is passed what should happen" ?  In any case, it seems there is some
common agreement that directories should be ignored not matter what
the predicate says.

> > I.e. can (locate-file f p s 'file-readable-p) return a directory ?
> >
> > "Yes" is better since it allows the caller to choose whether
> > directories are considered or not but "no" is better because it
> > allows (locate-file file path suffixes 'file-executable-p) to behave
> > like your current (locate-file file path suffixes 'executable).  Or
> > does the current XEmacs code always consider directories anyway ?
> 
> I think it is ok for a function named `locate-file' to ignore
> directories.

That's true, but I was just thinking of the case where someone
needs to look through a path for a particular subdirectory.
Like look for the X11 subdirectory in
/usr/include:/usr/X11R6/include:/usr/local/include:/usr/share/include:...
It would be convenient to be able to use locate-file for it as well
just by passing an appropriate predicate.


	Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 15:27             ` Stefan Monnier
  2002-04-18 16:20               ` Hrvoje Niksic
  2002-04-18 16:39               ` Eli Zaretskii
@ 2002-04-19  5:25               ` Richard Stallman
  2 siblings, 0 replies; 31+ messages in thread
From: Richard Stallman @ 2002-04-19  5:25 UTC (permalink / raw)
  Cc: hniksic, monnier+gnu/emacs, emacs-devel

    Based on the information here, I think I'll go ahead and implement
    the functionality on top of `openp' with just a `predicate' argument
    and without backward compatibility for `mode'.

We should support backward compatibility values of MODE such as
`executable' and `writable'.  That is a clean enough interface,
so there is no particular downside to supporting it.

We could allow predicates as alternative values for the same argument,
or we could add another optional argument PREDICATE.

    But I have one question left: should the `file-directory-p' check be enforced
    independently from `predicate' ?

Definitely yes--by default.  The default should be to
return only files, not directories.

There could be an additional optional argument which says "accept
directories too."  Perhaps it could also have a way to specify
that you want directories only.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-18 18:59                 ` Stefan Monnier
@ 2002-04-25 12:12                   ` Hrvoje Niksic
  2002-04-25 22:52                     ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-04-25 12:12 UTC (permalink / raw)


Has `locate-file' been installed?  I would just like to be aware of
the progress, and make sure that we're not incompatible.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-25 12:12                   ` Hrvoje Niksic
@ 2002-04-25 22:52                     ` Stefan Monnier
  2002-05-06 15:58                       ` Hrvoje Niksic
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-04-25 22:52 UTC (permalink / raw)
  Cc: emacs-devel

> Has `locate-file' been installed?

Not yet.

>  I would just like to be aware of
> the progress, and make sure that we're not incompatible.

I have most of the code ready but haven't had time to finish it up yet.
It will be compatible (including the `executable' and stuff that I don't
like ;-) but will allow general predicates.

Unless someone else does it before I get time to.


	Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-04-25 22:52                     ` Stefan Monnier
@ 2002-05-06 15:58                       ` Hrvoje Niksic
       [not found]                         ` <200205061655.g46Gt3K01382@rum.cs.yale.edu>
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-05-06 15:58 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> Has `locate-file' been installed?
>
> Not yet.
>
>>  I would just like to be aware of
>> the progress, and make sure that we're not incompatible.
>
> I have most of the code ready but haven't had time to finish it up yet.
> It will be compatible (including the `executable' and stuff that I don't
> like ;-) but will allow general predicates.

Can you give me the documentation?

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
       [not found]                         ` <200205061655.g46Gt3K01382@rum.cs.yale.edu>
@ 2002-05-06 19:53                           ` Hrvoje Niksic
       [not found]                             ` <200205062052.g46KqwO02482@rum.cs.yale.edu>
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-05-06 19:53 UTC (permalink / raw)
  Cc: emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> Search for FILENAME through PATH.
> If SUFFIXES is non-nil, it should be a list of suffixes to append to
> file name when searching.  If SUFFIXES is nil, it is equivalent to '("").
> If non-nil, PREDICATE is used instead of `file-readable-p'.
> PREDICATE can also be an integer to pass to the access(2) function,
> in which case file-name-handlers are ignored.
> For compatibility with XEmacs, PREDICATE can also be a symbol among
> `executable', `readable', `writable', or `exists' or a list of one
> of those symbols.

Why have you reverted to the old integer-based interface for
PREDICATE?  These days even "access(2)" uses preprocessor constants
for its second argument.  The user really shouldn't learn obscure
integer combinations when more readable symbols are available.

Besides, both the numbers and the symbols are compatible with XEmacs.
XEmacs supports (but does not document) the numbers and will do so in
the foreseeable future.  In fact, it will do so forever if it has to
be done for compatibility with your code, which reintroduces them.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
       [not found]                             ` <200205062052.g46KqwO02482@rum.cs.yale.edu>
@ 2002-05-06 20:59                               ` Hrvoje Niksic
  2002-05-06 21:12                                 ` Stefan Monnier
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-05-06 20:59 UTC (permalink / raw)
  Cc: rms, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

> Yes, the integer arguments should not be used.

Then could you please simply not document them?  Or mark those as
obsolete or "XEmacs-compatible"?

> 1 - they are (contrary to the symbolic args like `executable').
> 2 - since the code has to support them (for the above reason), I might as
>     well let the functionality be available from elisp rather than go
>     though the trouble of hiding it.

I agree with this.  They work in XEmacs too.  But they are being
deprecated, for good reason, as I explained in the previous message.
I would appreciate it if you deprecated them too.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-05-06 20:59                               ` Hrvoje Niksic
@ 2002-05-06 21:12                                 ` Stefan Monnier
  2002-05-06 21:57                                   ` Hrvoje Niksic
  0 siblings, 1 reply; 31+ messages in thread
From: Stefan Monnier @ 2002-05-06 21:12 UTC (permalink / raw)
  Cc: Stefan Monnier, rms, emacs-devel

> I agree with this.  They work in XEmacs too.  But they are being
> deprecated, for good reason, as I explained in the previous message.
> I would appreciate it if you deprecated them too.

Done.


	Stefan

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-05-06 21:12                                 ` Stefan Monnier
@ 2002-05-06 21:57                                   ` Hrvoje Niksic
  2002-05-07 20:06                                     ` Richard Stallman
  0 siblings, 1 reply; 31+ messages in thread
From: Hrvoje Niksic @ 2002-05-06 21:57 UTC (permalink / raw)
  Cc: rms, emacs-devel

"Stefan Monnier" <monnier+gnu/emacs@rum.cs.yale.edu> writes:

>> I agree with this.  They work in XEmacs too.  But they are being
>> deprecated, for good reason, as I explained in the previous message.
>> I would appreciate it if you deprecated them too.
>
> Done.

Thanks.  I'll take a look at implementing the generic PREDICATE.

BTW, my Lisp implementation might still be useful as a compatibility
function for people who want to use `locate-file' in older Emacsen.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: locate-file in Emacs
  2002-05-06 21:57                                   ` Hrvoje Niksic
@ 2002-05-07 20:06                                     ` Richard Stallman
  0 siblings, 0 replies; 31+ messages in thread
From: Richard Stallman @ 2002-05-07 20:06 UTC (permalink / raw)
  Cc: monnier+gnu/emacs, emacs-devel

    BTW, my Lisp implementation might still be useful as a compatibility
    function for people who want to use `locate-file' in older Emacsen.

We don't even think about supporting old versions of Emacs.
Just supporting the current version is plenty of work.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2002-05-07 20:06 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-04-17  5:05 locate-file in Emacs Hrvoje Niksic
2002-04-17  5:47 ` Eli Zaretskii
2002-04-17  8:53   ` Hrvoje Niksic
2002-04-17  9:28 ` Stefan Monnier
2002-04-17  9:47   ` Hrvoje Niksic
2002-04-17 10:01     ` Stefan Monnier
2002-04-18 13:16       ` Hrvoje Niksic
2002-04-18 13:54         ` Miles Bader
2002-04-18 14:09           ` Hrvoje Niksic
2002-04-18 14:25             ` Miles Bader
2002-04-18 14:08         ` Stefan Monnier
2002-04-18 15:11           ` Hrvoje Niksic
2002-04-18 15:27             ` Stefan Monnier
2002-04-18 16:20               ` Hrvoje Niksic
2002-04-18 18:59                 ` Stefan Monnier
2002-04-25 12:12                   ` Hrvoje Niksic
2002-04-25 22:52                     ` Stefan Monnier
2002-05-06 15:58                       ` Hrvoje Niksic
     [not found]                         ` <200205061655.g46Gt3K01382@rum.cs.yale.edu>
2002-05-06 19:53                           ` Hrvoje Niksic
     [not found]                             ` <200205062052.g46KqwO02482@rum.cs.yale.edu>
2002-05-06 20:59                               ` Hrvoje Niksic
2002-05-06 21:12                                 ` Stefan Monnier
2002-05-06 21:57                                   ` Hrvoje Niksic
2002-05-07 20:06                                     ` Richard Stallman
2002-04-18 16:39               ` Eli Zaretskii
2002-04-18 16:24                 ` Hrvoje Niksic
2002-04-19  5:25               ` Richard Stallman
2002-04-18 15:31             ` Miles Bader
2002-04-18 16:29               ` Hrvoje Niksic
2002-04-18 16:45                 ` Miles Bader
2002-04-18 16:49                   ` Hrvoje Niksic
2002-04-18 16:54                     ` Miles Bader

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).