Subject: bug#48317: 27.1; text-property-search-forward moves point to end when not found

From: Howard Melman <[email-masked]>
Date: Wed, 12 May 2021 12:29:10 -0400

On May 12, 2021, at 10:16 AM, Lars Ingebrigtsen <[email-masked]> wrote:

> Howard Melman <[email-masked]> writes:
> 
>>    ;; a region with the specfied face is found,
>>    ;; point is moved to the beginning of it
>>    (text-property-search-forward 'face 'font-lock-function-name-face)
>> 
> No, here you're looking for regions where `face' is not
> `font-lock-function-name-face' -- which will indeed leave you at the
> start of the region where `face' is `font-lock-function-name-face', but
> that's not really what the function matched.

I have read the above a dozen times and still am not sure I follow
it. AIUI since predicate is nil this is looking for regions where face
is not font-lock-function-name-face.  But how does that leave you at
the start of a region where face is indeed
font-lock-function-name-face?  

Is what it's doing leaving you at the end of a region where face isn't
font-lock-function-name-face? (Which thanks to Stephen Berman I
realize that the function leaving you at the beginning or end of a
match was very significant to understanding what was happening).  If
so I think that is not at all intuitive from reading the above line of
code.

> But I understand your confusion now.  

Thank you, I thought I was going crazy.

> The function searches for areas where a text property is matching
> something (according to PREDICATE), and leaves point at the end of the
> match.  You, instead, expect it to leave point at the start of the
> match, which is the opposite of what it does.

I want to be more explicit here.  I do expect it to search for areas
where a text property is matching something.  It of course is
dependent on the value of all of its arguments including PREDICATE,
though I'd expect the default value of PREDICATE to DTRT in the common
case.  I know that common can be misunderstood but for a search
function I thought I was on strong ground that "find the thing I
specify" is the common case.  I don't much care whether this function
leaves you at the start or end of the match, I'd expect to find out
that specific detail from the docstring or observed behavior.  And
usually if I'm lucky I find in the docstring, manual or code some
convenient idiom like your while loop example that makes this choice
very convenient in actual use.

AIUI, all of this confusion is because "leaves you at the end of a not
matching area" and "leaves you at the beginning of a matching area"
happen to be the same place if such an area exists, but is quite
different if it doesn't.

Or could have been avoided if the function was named 
goto-end-of-region-not-matching-text-property
which I *think* is an accurate (though horrible) name?

> Hm...  Oh!  That's wrong in the doc string, too -- it says that it moves
> point to the start of the region, which it certainly doesn't.  I've now
> fixed this in the two doc strings.

It's probably impossible to change in the signature because of
compatibility but perhaps this could inform the docstring.  AIUI if
this function is not passed a VALUE or PREDICATE it searches for
regions that contain PROPERTY (a "trick" because a property having a
nil value is the same as not being present).  But with just a VALUE it
searches for areas that don't have the PROPERTY/VALUE combo because
PREDICATE is nil.  And if PREDICATE is t it searches for areas that do
have that combo.

Since in lisp a default optional argument is nil, I think the behavior
with the default value of PREDICATE is reversed from what it should be
for a function named "search". Particularly since it changes the sense
of the function from when just PROPERTY is passed as opposed to when
PROPERTY and VALUE are passed (right?).

Your example of using this function with a while loop definitely helps
reveal its intended use.  Perhaps including one when passing VALUE to
the function would help?

I will happily commented on a proposed docstring if you post it here.
I've not signed papers but do I have to for docstring contributions?

Thanks.

Howard