* Re: Questions regarding char-table-range RANGE arg
2023-08-31 21:54 Questions regarding char-table-range RANGE arg Federico Tedin
@ 2023-09-01 7:34 ` Eli Zaretskii
2023-09-02 8:36 ` Federico Tedin
0 siblings, 1 reply; 3+ messages in thread
From: Eli Zaretskii @ 2023-09-01 7:34 UTC (permalink / raw)
To: Federico Tedin; +Cc: emacs-devel
> Date: Thu, 31 Aug 2023 23:54:01 +0200
> From: Federico Tedin <federicotedin@gmail.com>
>
> Hi everyone,
>
> I was trying to understand better how char tables work but I got stuck
> at the following:
>
> In the docs for `char-table-range'
> (https://www.gnu.org/software/emacs/manual/html_node/elisp/Char_002dTables.html),
> it is mentioned
> that it is possible to specify (from . to) as the value for RANGE. This
> already seemed a bit unexpected for me, as the function
> is supposed to retrieve a single value from the char table - how could
> it do it for a range, where potentially many different values
> could be defined?
Char-tables usually include whole ranges of characters with the same
value. The implementation of char-tables stores such ranges
efficiently, using just one slot instead of a separate slot for every
character. This is actually the main reason for having char-tables in
Emacs, and the main design goal for their implementation: to allow
efficient storage of character properties and quick access to those
properties by character code.
Thus, querying the value that is in effect for a range of characters
makes a lot of sense.
> I did some tests:
>
> (setq tt (make-char-table nil))
>
> (set-char-table-range tt (cons 10 20) "foo")
> (set-char-table-range tt (cons 21 25) "bar")
> [...]
> So from my tests it seems like only `from' is considered? Similar to the
> case where RANGE is just a character.
Basically yes (but see below).
> I was hoping someone
> with a better understanding of character tables could maybe explain the
> behaviour observed above. It is possible it could me just
> missinterpreting the documentation (I am trying to keep a more end-user
> perspective for this, i.e. not look at the Emacs source code
> and only use documentation). I did try looking also into
> chartab-tests.el though but could not find more information there.
The implementation is in chartab.c, you should look there for the
details.
What the implementation does is access the value at FROM, and then, if
TO is greater than FROM, shrink the range FROM..TO to the largest
range of character codes that have the same value as FROM. However,
the information about the shrunk range is not returned to the caller
of char-table-range. (If this is deemed important, we could add an
optional argument to char-table-range which, if non-nil, would cause
the function to return a list of, say, (FROM TO VALUE), where TO is
the actual value of the shrunk range.)
So in the examples you tried:
> (char-table-range tt (cons 5 15)) ; includes some "foo" values?
> -> nil ; no
Here TO was internally set to 9.
> (char-table-range tt (cons 15 22)) ; includes some "foo" and "bar" values?
> -> "foo" ; ok, only the first range was considered
Here, TO was internally set to 20.
> (char-table-range tt (cons 15 0)) ; what if I set `to' to a nonsensical
> value?
> -> "foo"
Here TO was ignored, because it is smaller than FROM.
> (char-table-range tt (cons 15 99999)) ; or this one
> -> "foo"
Here TO was internally set to 20.
I hope this answers your questions.
^ permalink raw reply [flat|nested] 3+ messages in thread