unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Qs on obarrays
@ 2005-10-12  0:52 Drew Adams
  0 siblings, 0 replies; 8+ messages in thread
From: Drew Adams @ 2005-10-12  0:52 UTC (permalink / raw)


The Elisp manual hints that you can create and fill an obarray like this:

(let ((my-obarray (make-vector 7 0)))
  (dolist (name my-names) (intern name my-obarray))
  (completing-read "XXX: " my-obarray))

That works. And this also works:

(let ((my-obarray (make-vector 7 0)))
  (dolist (name my-names) (intern name my-obarray))
  (all-completions "" my-obarray))

However, this does not seem to work for me:

(let ((my-obarray (make-vector 7 0)))
  (dolist (name my-names) (intern name my-obarray))
  (all-completions "" my-obarray 'commandp))

Even if all of my-names are symbol-names of commands, this always returns
nil. Any idea why?

Also, the obarray length must be supplied to make-vector. Anyone know a
heuristic for a good vector length to use when you expect a certain number
of symbols? I notice that the length of standard variable `obarray's value
is 1511 (prime, presumably). If I expect on the order of N symbols, what is
a good length to use? Or is there no simple formula? If not, anyone know a
good length for, say, 100 symbols?

(BTW - The obarray vector itself does not show all of the interned symbols,
when printed. I assume this is because if there are multiple symbols in the
same bucket only one of them can be printed when the vector is shown.)

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

* Re: Qs on obarrays
       [not found] <mailman.10964.1129078391.20277.help-gnu-emacs@gnu.org>
@ 2005-10-12  1:32 ` Pascal Bourguignon
  2005-10-12  2:02   ` Drew Adams
  2005-10-12 16:17   ` Kevin Rodgers
  2005-10-12 15:53 ` Stefan Monnier
  1 sibling, 2 replies; 8+ messages in thread
From: Pascal Bourguignon @ 2005-10-12  1:32 UTC (permalink / raw)


"Drew Adams" <drew.adams@oracle.com> writes:

> The Elisp manual hints that you can create and fill an obarray like this:
>
> (let ((my-obarray (make-vector 7 0)))
>   (dolist (name my-names) (intern name my-obarray))
>   (completing-read "XXX: " my-obarray))
>
> That works. And this also works:
>
> (let ((my-obarray (make-vector 7 0)))
>   (dolist (name my-names) (intern name my-obarray))
>   (all-completions "" my-obarray))
>
> However, this does not seem to work for me:
>
> (let ((my-obarray (make-vector 7 0)))
>   (dolist (name my-names) (intern name my-obarray))
>   (all-completions "" my-obarray 'commandp))
>
> Even if all of my-names are symbol-names of commands, this always returns
> nil. Any idea why?

Because symbols are objects, they have their own identity.  When a
symbol is used to name a function or command, it's the symbol identity
that's used, not its name (otherwise we would use strings to name
functions!).

Try this:

(defmacro defun-with-symbol (name args &rest body)
   `(defun ,(eval name) ,args ,@body))

(let ((my-obarray (make-vector 7 0)))
  (defun-with-symbol (intern "insert-hello" my-obarray) ()
     (interactive)
     (insert "Hello "))
  (defun-with-symbol (intern "insert-world" my-obarray) ()
     (interactive)
     (insert "World! "))
  (funcall (intern "insert-hello" my-obarray))
  (funcall (intern "insert-world" my-obarray))
  (all-completions "" my-obarray 'commandp))


Of course, you may have difficulties to access to these commands since
they're interned in a different obarray.  Unfortunately emacs isn't
based on Common Lisp, and doesn't have packages.  In CL, one would
write (my-obarray::insert-hello) or M-x my-obarray::insert-hello RET
to call the command...



> Also, the obarray length must be supplied to make-vector. Anyone know a
> heuristic for a good vector length to use when you expect a certain number
> of symbols? I notice that the length of standard variable `obarray's value
> is 1511 (prime, presumably). If I expect on the order of N symbols, what is
> a good length to use? Or is there no simple formula? If not, anyone know a
> good length for, say, 100 symbols?

A prime number that's slightly greater than the maximum number of
symbols would be a good length.

> (BTW - The obarray vector itself does not show all of the interned symbols,
> when printed. I assume this is because if there are multiple symbols in the
> same bucket only one of them can be printed when the vector is shown.)

Indeed.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The mighty hunter
Returns with gifts of plump birds,
Your foot just squashed one.

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

* RE: Qs on obarrays
  2005-10-12  1:32 ` Qs on obarrays Pascal Bourguignon
@ 2005-10-12  2:02   ` Drew Adams
  2005-10-12 16:17   ` Kevin Rodgers
  1 sibling, 0 replies; 8+ messages in thread
From: Drew Adams @ 2005-10-12  2:02 UTC (permalink / raw)


    Because symbols are objects, they have their own identity.  When a
    symbol is used to name a function or command, it's the symbol identity
    that's used.

Of course! Great explanation. Thanks.

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

* Re: Qs on obarrays
       [not found] <mailman.10964.1129078391.20277.help-gnu-emacs@gnu.org>
  2005-10-12  1:32 ` Qs on obarrays Pascal Bourguignon
@ 2005-10-12 15:53 ` Stefan Monnier
  1 sibling, 0 replies; 8+ messages in thread
From: Stefan Monnier @ 2005-10-12 15:53 UTC (permalink / raw)


> Also, the obarray length must be supplied to make-vector. Anyone know a
> heuristic for a good vector length to use when you expect a certain number
> of symbols? I notice that the length of standard variable `obarray's value
> is 1511 (prime, presumably). If I expect on the order of N symbols, what is
> a good length to use? Or is there no simple formula? If not, anyone know a
> good length for, say, 100 symbols?

In most cases, you can advantageously use a hashtable instead of an obarray.
Those are automatically resized.


        Stefan

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

* Re: Qs on obarrays
  2005-10-12  1:32 ` Qs on obarrays Pascal Bourguignon
  2005-10-12  2:02   ` Drew Adams
@ 2005-10-12 16:17   ` Kevin Rodgers
  2005-10-12 17:14     ` Drew Adams
  1 sibling, 1 reply; 8+ messages in thread
From: Kevin Rodgers @ 2005-10-12 16:17 UTC (permalink / raw)


Pascal Bourguignon wrote:
 > "Drew Adams" <drew.adams@oracle.com> writes:
 >>However, this does not seem to work for me:
 >>
 >>(let ((my-obarray (make-vector 7 0)))
 >>  (dolist (name my-names) (intern name my-obarray))
 >>  (all-completions "" my-obarray 'commandp))
 >>
 >>Even if all of my-names are symbol-names of commands, this always returns
 >>nil. Any idea why?
 >
 > Because symbols are objects, they have their own identity.  When a
 > symbol is used to name a function or command, it's the symbol identity
 > that's used, not its name (otherwise we would use strings to name
 > functions!).
 >
 > Try this:
 >
 > (defmacro defun-with-symbol (name args &rest body)
 >    `(defun ,(eval name) ,args ,@body))
 >
 > (let ((my-obarray (make-vector 7 0)))
 >   (defun-with-symbol (intern "insert-hello" my-obarray) ()
 >      (interactive)
 >      (insert "Hello "))
 >   (defun-with-symbol (intern "insert-world" my-obarray) ()
 >      (interactive)
 >      (insert "World! "))
 >   (funcall (intern "insert-hello" my-obarray))
 >   (funcall (intern "insert-world" my-obarray))
 >   (all-completions "" my-obarray 'commandp))

An alternative is to change just the predicate to check the standard
obarray:

(let ((my-obarray (make-vector 7 0)))
   (dolist (name my-names) (intern name my-obarray))
   (all-completions "" my-obarray
                    (lambda (symbol)
                      (commandp (intern (symbol-name symbol))))))

-- 
Kevin

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

* RE: Qs on obarrays
  2005-10-12 16:17   ` Kevin Rodgers
@ 2005-10-12 17:14     ` Drew Adams
  2005-10-12 18:23       ` Kevin Rodgers
  0 siblings, 1 reply; 8+ messages in thread
From: Drew Adams @ 2005-10-12 17:14 UTC (permalink / raw)


    An alternative is to change just the predicate to check the standard
    obarray:

    (let ((my-obarray (make-vector 7 0)))
       (dolist (name my-names) (intern name my-obarray))
       (all-completions "" my-obarray
                        (lambda (symbol)
                          (commandp (intern (symbol-name symbol))))))

I ended up doing something similar, since the original predicate (commandp)
will only work with the standard `obarray' (as Pascal pointed out so well).

Actually, I don't bother creating a new obarray, after all. I just use an
alist  (easier to manipulate) and redefine the predicate to work with that:

(all-completions "" my-alist (lambda (elt) (commandp (intern (car elt)))))

Or, more generally (what I really do):

(when (arrayp minibuffer-completion-table)
  (setq minibuffer-completion-predicate
        `(lambda (elt)
            (funcall ',minibuffer-completion-predicate
                     (intern (car elt))))))
(setq minibuffer-completion-table
      my-alist) ; Built by filtering `minibuffer-completion-table'.
...
(all-completions "" minibuffer-completion-table
                 minibuffer-completion-predicate)

Thanks to all for the input.

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

* Re: Qs on obarrays
  2005-10-12 17:14     ` Drew Adams
@ 2005-10-12 18:23       ` Kevin Rodgers
  2005-10-12 20:24         ` Drew Adams
  0 siblings, 1 reply; 8+ messages in thread
From: Kevin Rodgers @ 2005-10-12 18:23 UTC (permalink / raw)


Drew Adams wrote:
 > Actually, I don't bother creating a new obarray, after all. I just use an
 > alist  (easier to manipulate) and redefine the predicate to work with 
that:
 >
 > (all-completions "" my-alist (lambda (elt) (commandp (intern (car 
elt)))))
 >
 > Or, more generally (what I really do):
 >
 > (when (arrayp minibuffer-completion-table)
 >   (setq minibuffer-completion-predicate
 >         `(lambda (elt)
 >             (funcall ',minibuffer-completion-predicate
 >                      (intern (car elt))))))
 > (setq minibuffer-completion-table
 >       my-alist) ; Built by filtering `minibuffer-completion-table'.
 > ...
 > (all-completions "" minibuffer-completion-table
 >                  minibuffer-completion-predicate)

I wouldn't recommend setq'ing minibuffer-completion-table and
-predicate.  Those variables (plus -confirm) are let-bound by Emacs' own
higher level completion functions, and I think it'd be cleaner if you
did the same -- or just set your own my-completion-table and -predicate
variables, since you're passing their values explicitly to
all-completions anyway.

-- 
Kevin Rodgers

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

* RE: Qs on obarrays
  2005-10-12 18:23       ` Kevin Rodgers
@ 2005-10-12 20:24         ` Drew Adams
  0 siblings, 0 replies; 8+ messages in thread
From: Drew Adams @ 2005-10-12 20:24 UTC (permalink / raw)


    I wouldn't recommend setq'ing minibuffer-completion-table and
    -predicate.  Those variables (plus -confirm) are let-bound by Emacs' own
    higher level completion functions, and I think it'd be cleaner if you
    did the same -- or just set your own my-completion-table and -predicate
    variables, since you're passing their values explicitly to
    all-completions anyway.

In my case, only part of which I showed, it's actually appropriate to use
setq, and I do (also) use my own my-completion-* variables.

But what you say is a good general rule, and not just for
minibuffer-completion-*, and not just when other code let-binds the
variable.

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

end of thread, other threads:[~2005-10-12 20:24 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.10964.1129078391.20277.help-gnu-emacs@gnu.org>
2005-10-12  1:32 ` Qs on obarrays Pascal Bourguignon
2005-10-12  2:02   ` Drew Adams
2005-10-12 16:17   ` Kevin Rodgers
2005-10-12 17:14     ` Drew Adams
2005-10-12 18:23       ` Kevin Rodgers
2005-10-12 20:24         ` Drew Adams
2005-10-12 15:53 ` Stefan Monnier
2005-10-12  0:52 Drew Adams

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).