* 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
[parent not found: <mailman.10964.1129078391.20277.help-gnu-emacs@gnu.org>]
* 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 ` 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
2005-10-12 1:32 ` 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
* 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 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
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 --
2005-10-12 0:52 Qs on obarrays Drew Adams
[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 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
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).