unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#19208: replace-match unhelpful error message
@ 2014-11-28 17:00 Phillip Lord
  2019-08-03 14:01 ` Lars Ingebrigtsen
  2019-08-03 20:22 ` Paul Eggert
  0 siblings, 2 replies; 15+ messages in thread
From: Phillip Lord @ 2014-11-28 17:00 UTC (permalink / raw)
  To: 19208


Occurs in Emacs 24.3 and trunk

Running this code in *scratch* buffer

(progn
  (goto-char (point-min))
  (re-search-forward "This")
  (replace-match "That" nil nil nil))

Now undo and run this code

(progn
  (goto-char (point-min))
  (re-search-forward "This")
  (replace-match "That" nil nil nil 1))

This causes the following error.

progn: Args out of range: -1, -1


The error is caused because I have asked for a subexp that doesn't exist in
the regexp. A programmer error for sure, but the Args out of range error seems
rather unfriendly to me, especially as I have no idea where the -1, or
-1 has come from.

"Attempt to replace regexp subexpression that doesn't exist", for
example, would be nicer.







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

* bug#19208: replace-match unhelpful error message
  2014-11-28 17:00 bug#19208: replace-match unhelpful error message Phillip Lord
@ 2019-08-03 14:01 ` Lars Ingebrigtsen
  2019-08-03 20:22 ` Paul Eggert
  1 sibling, 0 replies; 15+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-03 14:01 UTC (permalink / raw)
  To: Phillip Lord; +Cc: 19208

phillip.lord@newcastle.ac.uk (Phillip Lord) writes:

> (progn
>   (goto-char (point-min))
>   (re-search-forward "This")
>   (replace-match "That" nil nil nil 1))
>
> This causes the following error.
>
> progn: Args out of range: -1, -1
>
> The error is caused because I have asked for a subexp that doesn't exist in
> the regexp. A programmer error for sure, but the Args out of range error seems
> rather unfriendly to me, especially as I have no idea where the -1, or
> -1 has come from.
>
> "Attempt to replace regexp subexpression that doesn't exist", for
> example, would be nicer.

Yup.

This is the code that signals the error:

      if (search_regs.start[sub] < BEGV
	  || search_regs.start[sub] > search_regs.end[sub]
	  || search_regs.end[sub] > ZV)
	args_out_of_range (make_fixnum (search_regs.start[sub]),
			   make_fixnum (search_regs.end[sub]));

Which is a weird way to check for this, surely?  It looks more like a
sanity checks that checks whether start[sub] and end[sub] is inside the
buffer, and that the start is before the end.

This happens to actually work here because when there is no match,
start[sub] is -1, which is always less than BEGV.

And this explains where the -1 in the args out of range comes from.

The sanity check seems sensible (because the buffer may have been
narrowed before calling replace-match), so I propose to add an
additional check that actually explicitly checks whether the subexp is
valid.

Hm...  or is this what the check right above it tried to do?

  if (NILP (subexp))
    sub = 0;
  else
    {
      CHECK_FIXNUM (subexp);
      if (! (0 <= XFIXNUM (subexp) && XFIXNUM (subexp) < search_regs.num_regs))
	args_out_of_range (subexp, make_fixnum (search_regs.num_regs));
      sub = XFIXNUM (subexp);
    }

Yoda conditionals and a !...  Let's see...

No, that's just another sanity check -- num_regs is the max allowed
number of sub-matches.  (I've now added some comments to clarify.)

I've now added a new check to check for this situation, and I've used
your suggested error string.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#19208: replace-match unhelpful error message
  2014-11-28 17:00 bug#19208: replace-match unhelpful error message Phillip Lord
  2019-08-03 14:01 ` Lars Ingebrigtsen
@ 2019-08-03 20:22 ` Paul Eggert
  2019-08-03 20:31   ` Lars Ingebrigtsen
  2019-08-04  9:18   ` Andreas Schwab
  1 sibling, 2 replies; 15+ messages in thread
From: Paul Eggert @ 2019-08-03 20:22 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19208, Phillip Lord

[-- Attachment #1: Type: text/plain, Size: 1298 bytes --]

> No, that's just another sanity check -- num_regs is the max allowed
> number of sub-matches.  (I've now added some comments to clarify.)

Unfortunately that patch messes up the sanity check, as the patched code allows 
'sub' to be negative, or to be equal to search_regs.num_regs, and in either case 
this results in a bad pointer.

> Yoda conditionals and a !...

Actually those were Leibniz conditionals, which are comparisons involving "<" or 
"<=". The idea is that the conditionals' textual order reflects numeric order. 
This is a common style in math when doing range checking, e.g., "0 <= i < n". 
Yoda conditionals are expressions like "0 != x" which I agree are confusing.

I learned Leibniz conditionals from the late Val Schorre, who was *really* good 
at programming and programming style: Knuth credits Schorre with the invention 
of goto-less programming in the early 1960s. When I redid your patch as a 
Leibniz conditional, I instantly spotted the bug that it introduced. You might 
give Leibniz conditionals a try, as they help make code more readable and 
reliable when checking for range errors or overflow.

While in the neighborhood I spotted some other rare possibilities for bad 
behavior due to out-of-range indexes. I fixed the bugs I found by installing the 
attached.

[-- Attachment #2: 0001-Fix-rare-undefined-behaviors-in-replace-match.patch --]
[-- Type: text/x-patch, Size: 8020 bytes --]

From 13fe8a27042b1539d43727e6df97c386c61c3053 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 3 Aug 2019 12:45:19 -0700
Subject: [PATCH] Fix rare undefined behaviors in replace-match

* src/search.c (Freplace_match): Simplify by caching search_regs
components.  Fix sanity check for out-of-range subscripts;
it incorrectly allowed negative subscripts, subscripts
equal to search_regs.num_regs, and it had undefined
behavior for subscripts outside ptrdiff_t range.
Improve wording of newly-introduced replace-match diagnostic.
Rework use of opoint, to avoid setting point to an out-of-range value
in rare cases involving modification hooks.
---
 src/search.c | 107 ++++++++++++++++++---------------------------------
 1 file changed, 38 insertions(+), 69 deletions(-)

diff --git a/src/search.c b/src/search.c
index 0e2ae059e8..9b674a5810 100644
--- a/src/search.c
+++ b/src/search.c
@@ -2389,44 +2389,32 @@ since only regular expressions have distinguished subexpressions.  */)
   case_action = nochange;	/* We tried an initialization */
 				/* but some C compilers blew it */
 
-  if (search_regs.num_regs <= 0)
+  ptrdiff_t num_regs = search_regs.num_regs;
+  if (num_regs <= 0)
     error ("`replace-match' called before any match found");
 
   if (NILP (subexp))
     sub = 0;
   else
     {
-      CHECK_FIXNUM (subexp);
+      CHECK_RANGED_INTEGER (subexp, 0, num_regs - 1);
       sub = XFIXNUM (subexp);
-      /* Sanity check to see whether the subexp is larger than the
-	 allowed number of sub-regexps. */
-      if (sub >= 0 && sub > search_regs.num_regs)
-	args_out_of_range (subexp, make_fixnum (search_regs.num_regs));
     }
 
-  /* Check whether the subexpression to replace is greater than the
-     number of subexpressions in the regexp. */
-  if (sub > 0 && search_regs.start[sub] == -1)
-    args_out_of_range (build_string ("Attempt to replace regexp subexpression that doesn't exist"),
-		       subexp);
+  ptrdiff_t sub_start = search_regs.start[sub];
+  ptrdiff_t sub_end = search_regs.end[sub];
+  eassert (sub_start <= sub_end);
 
-  /* Sanity check to see whether the text to replace is present in the
-     buffer/string. */
-  if (NILP (string))
+  /* Check whether the text to replace is present in the buffer/string.  */
+  if (! (NILP (string)
+	 ? BEGV <= sub_start && sub_end <= ZV
+	 : 0 <= sub_start && sub_end <= SCHARS (string)))
     {
-      if (search_regs.start[sub] < BEGV
-	  || search_regs.start[sub] > search_regs.end[sub]
-	  || search_regs.end[sub] > ZV)
-	args_out_of_range (make_fixnum (search_regs.start[sub]),
-			   make_fixnum (search_regs.end[sub]));
-    }
-  else
-    {
-      if (search_regs.start[sub] < 0
-	  || search_regs.start[sub] > search_regs.end[sub]
-	  || search_regs.end[sub] > SCHARS (string))
-	args_out_of_range (make_fixnum (search_regs.start[sub]),
-			   make_fixnum (search_regs.end[sub]));
+      if (sub_start < 0)
+	xsignal2 (Qerror,
+		  build_string ("replace-match subexpression does not exist"),
+		  subexp);
+      args_out_of_range (make_fixnum (sub_start), make_fixnum (sub_end));
     }
 
   if (NILP (fixedcase))
@@ -2434,8 +2422,8 @@ since only regular expressions have distinguished subexpressions.  */)
       /* Decide how to casify by examining the matched text. */
       ptrdiff_t last;
 
-      pos = search_regs.start[sub];
-      last = search_regs.end[sub];
+      pos = sub_start;
+      last = sub_end;
 
       if (NILP (string))
 	pos_byte = CHAR_TO_BYTE (pos);
@@ -2511,9 +2499,8 @@ since only regular expressions have distinguished subexpressions.  */)
     {
       Lisp_Object before, after;
 
-      before = Fsubstring (string, make_fixnum (0),
-			   make_fixnum (search_regs.start[sub]));
-      after = Fsubstring (string, make_fixnum (search_regs.end[sub]), Qnil);
+      before = Fsubstring (string, make_fixnum (0), make_fixnum (sub_start));
+      after = Fsubstring (string, make_fixnum (sub_end), Qnil);
 
       /* Substitute parts of the match into NEWTEXT
 	 if desired.  */
@@ -2542,12 +2529,12 @@ since only regular expressions have distinguished subexpressions.  */)
 
 		  if (c == '&')
 		    {
-		      substart = search_regs.start[sub];
-		      subend = search_regs.end[sub];
+		      substart = sub_start;
+		      subend = sub_end;
 		    }
 		  else if (c >= '1' && c <= '9')
 		    {
-		      if (c - '0' < search_regs.num_regs
+		      if (c - '0' < num_regs
 			  && search_regs.start[c - '0'] >= 0)
 			{
 			  substart = search_regs.start[c - '0'];
@@ -2612,13 +2599,8 @@ since only regular expressions have distinguished subexpressions.  */)
       return concat3 (before, newtext, after);
     }
 
-  /* Record point, then move (quietly) to the start of the match.  */
-  if (PT >= search_regs.end[sub])
-    opoint = PT - ZV;
-  else if (PT > search_regs.start[sub])
-    opoint = search_regs.end[sub] - ZV;
-  else
-    opoint = PT;
+  /* Record point.  A nonpositive OPOINT is actually an offset from ZV.  */
+  opoint = PT <= sub_start ? PT : max (PT, sub_end) - ZV;
 
   /* If we want non-literal replacement,
      perform substitution on the replacement string.  */
@@ -2687,7 +2669,7 @@ since only regular expressions have distinguished subexpressions.  */)
 
 	      if (c == '&')
 		idx = sub;
-	      else if (c >= '1' && c <= '9' && c - '0' < search_regs.num_regs)
+	      else if ('1' <= c && c <= '9' && c - '0' < num_regs)
 		{
 		  if (search_regs.start[c - '0'] >= 1)
 		    idx = c - '0';
@@ -2745,25 +2727,11 @@ since only regular expressions have distinguished subexpressions.  */)
       xfree (substed);
     }
 
-  /* The functions below modify the buffer, so they could trigger
-     various modification hooks (see signal_before_change and
-     signal_after_change).  If these hooks clobber the match data we
-     error out since otherwise this will result in confusing bugs.  */
-  ptrdiff_t sub_start = search_regs.start[sub];
-  ptrdiff_t sub_end = search_regs.end[sub];
-  ptrdiff_t num_regs = search_regs.num_regs;
-  newpoint = search_regs.start[sub] + SCHARS (newtext);
+  newpoint = sub_start + SCHARS (newtext);
+  ptrdiff_t newstart = sub_start == sub_end ? newpoint : sub_start;
 
   /* Replace the old text with the new in the cleanest possible way.  */
-  replace_range (search_regs.start[sub], search_regs.end[sub],
-                 newtext, 1, 0, 1, 1);
-  /* Update saved data to match adjustment made by replace_range.  */
-  {
-    ptrdiff_t change = newpoint - sub_end;
-    if (sub_start >= sub_end)
-      sub_start += change;
-    sub_end += change;
-  }
+  replace_range (sub_start, sub_end, newtext, 1, 0, 1, true);
 
   if (case_action == all_caps)
     Fupcase_region (make_fixnum (search_regs.start[sub]),
@@ -2773,17 +2741,18 @@ since only regular expressions have distinguished subexpressions.  */)
     Fupcase_initials_region (make_fixnum (search_regs.start[sub]),
 			     make_fixnum (newpoint));
 
-  if (search_regs.start[sub] != sub_start
-      || search_regs.end[sub] != sub_end
-      || search_regs.num_regs != num_regs)
+  /* The replace_range etc. functions can trigger modification hooks
+     (see signal_before_change and signal_after_change).  Try to error
+     out if these hooks clobber the match data since clobbering can
+     result in confusing bugs.  Although this sanity check does not
+     catch all possible clobberings, it should catch many of them.  */
+  if (! (search_regs.num_regs == num_regs
+	 && search_regs.start[sub] == newstart
+	 && search_regs.end[sub] == newpoint))
     error ("Match data clobbered by buffer modification hooks");
 
-  /* Put point back where it was in the text.  */
-  if (opoint <= 0)
-    TEMP_SET_PT (opoint + ZV);
-  else
-    TEMP_SET_PT (opoint);
-
+  /* Put point back where it was in the text, if possible.  */
+  TEMP_SET_PT (clip_to_bounds (BEGV, opoint + (opoint <= 0 ? ZV : 0), ZV));
   /* Now move point "officially" to the start of the inserted replacement.  */
   move_if_not_intangible (newpoint);
 
-- 
2.17.1


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

* bug#19208: replace-match unhelpful error message
  2019-08-03 20:22 ` Paul Eggert
@ 2019-08-03 20:31   ` Lars Ingebrigtsen
  2019-08-03 20:50     ` Paul Eggert
  2019-08-03 23:59     ` Noam Postavsky
  2019-08-04  9:18   ` Andreas Schwab
  1 sibling, 2 replies; 15+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-03 20:31 UTC (permalink / raw)
  To: Paul Eggert; +Cc: 19208, Phillip Lord

Paul Eggert <eggert@cs.ucla.edu> writes:

>> No, that's just another sanity check -- num_regs is the max allowed
>> number of sub-matches.  (I've now added some comments to clarify.)
>
> Unfortunately that patch messes up the sanity check, as the patched
> code allows 'sub' to be negative, or to be equal to
> search_regs.num_regs, and in either case this results in a bad
> pointer.

Sorry; thanks for fixing.

>> Yoda conditionals and a !...
>
> Actually those were Leibniz conditionals, which are comparisons
> involving "<" or "<=". The idea is that the conditionals' textual
> order reflects numeric order. This is a common style in math when
> doing range checking, e.g., "0 <= i < n". Yoda conditionals are
> expressions like "0 != x" which I agree are confusing.

Well, I think both are called Yoda conditionals, and they are
demonstrably confusing for people not used to seeing conditionals
written that way, which is I think pretty much everybody, except four
people working on Emacs.  :-)

In real life, nobody says "if 62 is less than your age, you're eligible
for Medicare".  I think one should write code for legibility -- but
opinions on what's legible various, of course.  Reading "if (62 < age)",
for me, requires mental gymnastics.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 20:31   ` Lars Ingebrigtsen
@ 2019-08-03 20:50     ` Paul Eggert
  2019-08-04  9:09       ` Andreas Schwab
  2019-08-03 23:59     ` Noam Postavsky
  1 sibling, 1 reply; 15+ messages in thread
From: Paul Eggert @ 2019-08-03 20:50 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: 19208, Phillip Lord

Lars Ingebrigtsen wrote:
> they are
> demonstrably confusing for people not used to seeing conditionals
> written that way, which is I think pretty much everybody, except four
> people working on Emacs.  :-)

Just four?  :-)  (Actually the style is also used in other GNU projects.)

In this particular case the Leibniz style caught a potentially-serious bug. 
Although I understand that it can be a minor irritation for newcomers, it is 
quite useful for range checking and in practice I find that its reliability 
outweighs any irritation. (I didn't like Val Schorre's advice either, when I 
first heard it - but he was right.)





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 20:31   ` Lars Ingebrigtsen
  2019-08-03 20:50     ` Paul Eggert
@ 2019-08-03 23:59     ` Noam Postavsky
  2019-08-04  9:02       ` Andreas Schwab
  2019-08-04 11:47       ` Lars Ingebrigtsen
  1 sibling, 2 replies; 15+ messages in thread
From: Noam Postavsky @ 2019-08-03 23:59 UTC (permalink / raw)
  To: Lars Ingebrigtsen; +Cc: Phillip Lord, 19208, Paul Eggert


>> Actually those were Leibniz conditionals, which are comparisons
>> involving "<" or "<=". The idea is that the conditionals' textual
>> order reflects numeric order. This is a common style in math when
>> doing range checking, e.g., "0 <= i < n". Yoda conditionals are
>> expressions like "0 != x" which I agree are confusing.
>
> Well, I think both are called Yoda conditionals, and they are
> demonstrably confusing for people not used to seeing conditionals
> written that way, which is I think pretty much everybody, except four
> people working on Emacs.  :-)
>
> In real life, nobody says "if 62 is less than your age, you're eligible
> for Medicare".

People might say things like "your height must be between 120 and 200 cm
to ride this roller coaster" as opposed to "your height must be more
than 120 cm and your height must be less than 200 cm".

> I think one should write code for legibility -- but opinions on what's
> legible various, of course.  Reading "if (62 < age)", for me, requires
> mental gymnastics.

"if (height > 120 && height < 200)" require mental gymnastics, for me,
because each comparison is a different direction.





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 23:59     ` Noam Postavsky
@ 2019-08-04  9:02       ` Andreas Schwab
  2019-08-04 14:12         ` Noam Postavsky
  2019-08-04 11:47       ` Lars Ingebrigtsen
  1 sibling, 1 reply; 15+ messages in thread
From: Andreas Schwab @ 2019-08-04  9:02 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Phillip Lord, Lars Ingebrigtsen, 19208, Paul Eggert

On Aug 03 2019, Noam Postavsky <npostavs@gmail.com> wrote:

> People might say things like "your height must be between 120 and 200 cm
> to ride this roller coaster"

This still puts "height" (the variable) first.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 20:50     ` Paul Eggert
@ 2019-08-04  9:09       ` Andreas Schwab
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Schwab @ 2019-08-04  9:09 UTC (permalink / raw)
  To: Paul Eggert; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord

On Aug 03 2019, Paul Eggert <eggert@cs.ucla.edu> wrote:

> Lars Ingebrigtsen wrote:
>> they are
>> demonstrably confusing for people not used to seeing conditionals
>> written that way, which is I think pretty much everybody, except four
>> people working on Emacs.  :-)
>
> Just four?  :-)  (Actually the style is also used in other GNU projects.)

And always the same four people.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 20:22 ` Paul Eggert
  2019-08-03 20:31   ` Lars Ingebrigtsen
@ 2019-08-04  9:18   ` Andreas Schwab
  1 sibling, 0 replies; 15+ messages in thread
From: Andreas Schwab @ 2019-08-04  9:18 UTC (permalink / raw)
  To: Paul Eggert; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord

On Aug 03 2019, Paul Eggert <eggert@cs.ucla.edu> wrote:

> I learned Leibniz conditionals from the late Val Schorre, who was *really*
> good at programming and programming style: Knuth credits Schorre with the
> invention of goto-less programming in the early 1960s. When I redid your
> patch as a Leibniz conditional, I instantly spotted the bug that it
> introduced. You might give Leibniz conditionals a try, as they help make
> code more readable and reliable when checking for range errors or
> overflow.

Perhaps those that need that construct are not good enough to cope with
natural languages.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





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

* bug#19208: replace-match unhelpful error message
  2019-08-03 23:59     ` Noam Postavsky
  2019-08-04  9:02       ` Andreas Schwab
@ 2019-08-04 11:47       ` Lars Ingebrigtsen
  1 sibling, 0 replies; 15+ messages in thread
From: Lars Ingebrigtsen @ 2019-08-04 11:47 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: Phillip Lord, 19208, Paul Eggert

Noam Postavsky <npostavs@gmail.com> writes:

> People might say things like "your height must be between 120 and 200 cm
> to ride this roller coaster" as opposed to "your height must be more
> than 120 cm and your height must be less than 200 cm".

And they don't say "120 cm must be less than your height, which must also
be less than 200 cm".  :-)

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

* bug#19208: replace-match unhelpful error message
  2019-08-04  9:02       ` Andreas Schwab
@ 2019-08-04 14:12         ` Noam Postavsky
  2019-08-04 15:13           ` Andreas Schwab
  2019-08-05  2:25           ` Richard Stallman
  0 siblings, 2 replies; 15+ messages in thread
From: Noam Postavsky @ 2019-08-04 14:12 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord, Paul Eggert

Andreas Schwab <schwab@linux-m68k.org> writes:

> On Aug 03 2019, Noam Postavsky <npostavs@gmail.com> wrote:
>
>> People might say things like "your height must be between 120 and 200 cm
>> to ride this roller coaster"
>
> This still puts "height" (the variable) first.

Lars Ingebrigtsen <larsi@gnus.org> writes:
>
> And they don't say "120 cm must be less than your height, which must also
> be less than 200 cm".  :-)

Right, but unless we want to use a macro like

    IN_RANGE_P (height, 120, 200)

I think ((120 < height) && (height < 200)) is the closest we can get to
the natural phrasing.  In Elisp we can do (< 120 height 200) which is
nicer, but we're still stuck with `and' for semi-closed intervals.





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

* bug#19208: replace-match unhelpful error message
  2019-08-04 14:12         ` Noam Postavsky
@ 2019-08-04 15:13           ` Andreas Schwab
  2019-08-04 17:41             ` Paul Eggert
  2019-08-05  2:25           ` Richard Stallman
  1 sibling, 1 reply; 15+ messages in thread
From: Andreas Schwab @ 2019-08-04 15:13 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord, Paul Eggert

On Aug 04 2019, Noam Postavsky <npostavs@gmail.com> wrote:

> I think ((120 < height) && (height < 200)) is the closest we can get to
> the natural phrasing.

"X is between A and B" means "X is bigger than A and [X is] smaller than
B".  You would never say "A is smaller than X and [X is] smaller than
B".

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





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

* bug#19208: replace-match unhelpful error message
  2019-08-04 15:13           ` Andreas Schwab
@ 2019-08-04 17:41             ` Paul Eggert
  2019-08-04 18:14               ` Andreas Schwab
  0 siblings, 1 reply; 15+ messages in thread
From: Paul Eggert @ 2019-08-04 17:41 UTC (permalink / raw)
  To: Andreas Schwab, Noam Postavsky; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord

This is not strictly a question of what one would say in English, as 
mathematical notation is typically a better choice for mathematical notions. For 
example, in C it's typically better to write sixteen as "16" rather than as "6 + 
10" even though the latter is closer to the original English.

If we wanted code to mimic English better, COBOL would be a good choice. (Or 
maybe Perl. :-) But the goal is to write readable code, not to imitate how 
Anglo-Saxons talked.





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

* bug#19208: replace-match unhelpful error message
  2019-08-04 17:41             ` Paul Eggert
@ 2019-08-04 18:14               ` Andreas Schwab
  0 siblings, 0 replies; 15+ messages in thread
From: Andreas Schwab @ 2019-08-04 18:14 UTC (permalink / raw)
  To: Paul Eggert; +Cc: 19208, Lars Ingebrigtsen, Phillip Lord, Noam Postavsky

On Aug 04 2019, Paul Eggert <eggert@cs.ucla.edu> wrote:

> readable code

Exactly.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510  2552 DF73 E780 A9DA AEC1
"And now for something completely different."





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

* bug#19208: replace-match unhelpful error message
  2019-08-04 14:12         ` Noam Postavsky
  2019-08-04 15:13           ` Andreas Schwab
@ 2019-08-05  2:25           ` Richard Stallman
  1 sibling, 0 replies; 15+ messages in thread
From: Richard Stallman @ 2019-08-05  2:25 UTC (permalink / raw)
  To: Noam Postavsky; +Cc: 19208, larsi, phillip.lord, schwab, eggert

[[[ To any NSA and FBI agents reading my email: please consider    ]]]
[[[ whether defending the US Constitution against all enemies,     ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]

  > I think ((120 < height) && (height < 200)) is the closest we can get to
  > the natural phrasing.

That parallels the mathematical expression 120 < h < 200, which is a
plus, but doesn't parallel the textual form "height must be between
120 and 200", which is a minus.

The way to parallel the latter is (height > 120 && height < 200).

I think both of those are ok, but let's avoid other orderings
-- 
Dr Richard Stallman
President, Free Software Foundation (https://gnu.org, https://fsf.org)
Internet Hall-of-Famer (https://internethalloffame.org)







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

end of thread, other threads:[~2019-08-05  2:25 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-11-28 17:00 bug#19208: replace-match unhelpful error message Phillip Lord
2019-08-03 14:01 ` Lars Ingebrigtsen
2019-08-03 20:22 ` Paul Eggert
2019-08-03 20:31   ` Lars Ingebrigtsen
2019-08-03 20:50     ` Paul Eggert
2019-08-04  9:09       ` Andreas Schwab
2019-08-03 23:59     ` Noam Postavsky
2019-08-04  9:02       ` Andreas Schwab
2019-08-04 14:12         ` Noam Postavsky
2019-08-04 15:13           ` Andreas Schwab
2019-08-04 17:41             ` Paul Eggert
2019-08-04 18:14               ` Andreas Schwab
2019-08-05  2:25           ` Richard Stallman
2019-08-04 11:47       ` Lars Ingebrigtsen
2019-08-04  9:18   ` Andreas Schwab

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