all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* (goto-char ...) error
@ 2011-02-22 16:47 ken
  2011-02-22 17:31 ` Deniz Dogan
  0 siblings, 1 reply; 10+ messages in thread
From: ken @ 2011-02-22 16:47 UTC (permalink / raw)
  To: GNU Emacs List

Performing one search, I save the result with

(setq ptname (re-search-forward ...))

Then I want to back up one character and perform another search, so I do

(goto-char (- ptname 1))

But this pukes an error.  What's unkosher here?


tnx.



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

* Re: (goto-char ...) error
  2011-02-22 16:47 ken
@ 2011-02-22 17:31 ` Deniz Dogan
  2011-02-22 18:24   ` ken
       [not found]   ` <mailman.11.1298399070.22047.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 10+ messages in thread
From: Deniz Dogan @ 2011-02-22 17:31 UTC (permalink / raw)
  To: gebser; +Cc: GNU Emacs List

2011/2/22 ken <gebser@mousecar.com>:
> Performing one search, I save the result with
>
> (setq ptname (re-search-forward ...))
>
> Then I want to back up one character and perform another search, so I do
>
> (goto-char (- ptname 1))
>
> But this pukes an error.  What's unkosher here?
>

It's much easier if you tell us what the error is.

I tried to reproduce the problem using this code:

;; search for "a"
(let ((ptname (re-search-forward "a" nil t)))
  (when ptname
    (goto-char (- ptname 1))))

It all depends on how you use re-search-forward. As you can see in my
example, I pass t as the third argument meaning "don't error if you
can't find it, just return nil". I then make sure that ptname is
non-nil before I try to act on it using `-', otherwise we would be
doing (- nil 1) which makes no sense.

-- 
Deniz Dogan



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

* Re: (goto-char ...) error
  2011-02-22 17:31 ` Deniz Dogan
@ 2011-02-22 18:24   ` ken
  2011-02-22 18:45     ` Deniz Dogan
       [not found]   ` <mailman.11.1298399070.22047.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 10+ messages in thread
From: ken @ 2011-02-22 18:24 UTC (permalink / raw)
  To: GNU Emacs List


On 02/22/2011 12:31 PM Deniz Dogan wrote:
> 2011/2/22 ken <gebser@mousecar.com>:
>> Performing one search, I save the result with
>>
>> (setq ptname (re-search-forward ...))
>>
>> Then I want to back up one character and perform another search, so I do
>>
>> (goto-char (- ptname 1))
>>
>> But this pukes an error.  What's unkosher here?
>>
> 
> It's much easier if you tell us what the error is.
> 
> I tried to reproduce the problem using this code:
> 
> ;; search for "a"
> (let ((ptname (re-search-forward "a" nil t)))
>   (when ptname
>     (goto-char (- ptname 1))))
> 
> It all depends on how you use re-search-forward. As you can see in my
> example, I pass t as the third argument meaning "don't error if you
> can't find it, just return nil". I then make sure that ptname is
> non-nil before I try to act on it using `-', otherwise we would be
> doing (- nil 1) which makes no sense.
> 

My understanding is that the 4th arg to re-search-forward is to repeat
the search, so I set that to nil.

I get the same error whether the 3rd arg is t or nil (!?):

(setq ptname (re-search-forward "REGEXP" endpt t nil))
      (if ptname
	  ((goto-char (- ptname 1))
           ....

The error line in *Messages* says:

if: Invalid function: (goto-char (- begin-name-value 1))



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

* Re: (goto-char ...) error
  2011-02-22 18:24   ` ken
@ 2011-02-22 18:45     ` Deniz Dogan
  2011-02-22 19:22       ` ken
       [not found]       ` <mailman.1.1298402588.16069.help-gnu-emacs@gnu.org>
  0 siblings, 2 replies; 10+ messages in thread
From: Deniz Dogan @ 2011-02-22 18:45 UTC (permalink / raw)
  To: gebser; +Cc: GNU Emacs List

2011/2/22 ken <gebser@mousecar.com>:
>
> On 02/22/2011 12:31 PM Deniz Dogan wrote:
>> 2011/2/22 ken <gebser@mousecar.com>:
>>> Performing one search, I save the result with
>>>
>>> (setq ptname (re-search-forward ...))
>>>
>>> Then I want to back up one character and perform another search, so I do
>>>
>>> (goto-char (- ptname 1))
>>>
>>> But this pukes an error.  What's unkosher here?
>>>
>>
>> It's much easier if you tell us what the error is.
>>
>> I tried to reproduce the problem using this code:
>>
>> ;; search for "a"
>> (let ((ptname (re-search-forward "a" nil t)))
>>   (when ptname
>>     (goto-char (- ptname 1))))
>>
>> It all depends on how you use re-search-forward. As you can see in my
>> example, I pass t as the third argument meaning "don't error if you
>> can't find it, just return nil". I then make sure that ptname is
>> non-nil before I try to act on it using `-', otherwise we would be
>> doing (- nil 1) which makes no sense.
>>
>
> My understanding is that the 4th arg to re-search-forward is to repeat
> the search, so I set that to nil.
>
> I get the same error whether the 3rd arg is t or nil (!?):
>
> (setq ptname (re-search-forward "REGEXP" endpt t nil))
>      (if ptname
>          ((goto-char (- ptname 1))
>           ....
>
> The error line in *Messages* says:
>
> if: Invalid function: (goto-char (- begin-name-value 1))
>
>

You have one pair of parentheses too many.

Change:

((goto-char (- ptname 1))

to:

(goto-char (- ptname 1))

The error is telling you that "(goto-char (- ptname 1))" is an invalid
function, which could potentially be confusing, but it really makes
sense.  You call a function named `foo' like (foo ...), but if you do
"((foo ...))" you're trying to call a function named "(foo ...)" which
is not a valid function.

From the documentation of `if':

(if COND THEN ELSE...)
If COND yields non-nil, do THEN, else do ELSE...

This means that your THEN clause must be a single expression.
Everything starting with the third argument to `if' is considered part
of the ELSE clause.

If you want to multiple expressions in the THEN clause, use `progn' as
such:

(if (= x y)
    (progn
      (message "They're equal")
      (message "Hooray!"))
  (message "They're not equal.")
  (message "Too bad, bro."))

I hope that helps!

-- 
Deniz Dogan



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

* Re: (goto-char ...) error
  2011-02-22 18:45     ` Deniz Dogan
@ 2011-02-22 19:22       ` ken
  2011-02-22 19:45         ` Deniz Dogan
       [not found]       ` <mailman.1.1298402588.16069.help-gnu-emacs@gnu.org>
  1 sibling, 1 reply; 10+ messages in thread
From: ken @ 2011-02-22 19:22 UTC (permalink / raw)
  To: GNU Emacs List


On 02/22/2011 01:45 PM Deniz Dogan wrote:
> 2011/2/22 ken <gebser@mousecar.com>:
>> On 02/22/2011 12:31 PM Deniz Dogan wrote:
>>> 2011/2/22 ken <gebser@mousecar.com>:
>>>> ....
>>>
>> My understanding is that the 4th arg to re-search-forward is to repeat
>> the search, so I set that to nil.
>>
>> I get the same error whether the 3rd arg is t or nil (!?):
>>
>> (setq ptname (re-search-forward "REGEXP" endpt t nil))
>>      (if ptname
>>          ((goto-char (- ptname 1))
>>           ....
>>
>> The error line in *Messages* says:
>>
>> if: Invalid function: (goto-char (- begin-name-value 1))
>>
>>
> 
> You have one pair of parentheses too many.
> 
> Change:
> 
> ((goto-char (- ptname 1))
> 
> to:
> 
> (goto-char (- ptname 1))
> 
> The error is telling you that "(goto-char (- ptname 1))" is an invalid
> function, which could potentially be confusing, but it really makes
> sense.  You call a function named `foo' like (foo ...), but if you do
> "((foo ...))" you're trying to call a function named "(foo ...)" which
> is not a valid function.
> 
> From the documentation of `if':
> 
> (if COND THEN ELSE...)
> If COND yields non-nil, do THEN, else do ELSE...
> 
> This means that your THEN clause must be a single expression.
> Everything starting with the third argument to `if' is considered part
> of the ELSE clause.
> 
> If you want to multiple expressions in the THEN clause, use `progn' as
> such:
> 
> (if (= x y)
>     (progn
>       (message "They're equal")
>       (message "Hooray!"))
>   (message "They're not equal.")
>   (message "Too bad, bro."))
> 
> I hope that helps!

Yeah, I think it should.  Thanks.

Just to be clear about one more thing I'll be addressing subsequently,
i.e., another "if" nested inside the first:

(if (= x y)
   (progn
     (message "They're equal")
     (message "Hooray!")
     (if (= x z)
          (progn
            (message "The next one's equal too.")
            (message "Hooray++!")))) ; enuf )s to match up to 1st progn
 (message "They're not equal.")
 (message "Too bad, bro."))


elisp is weird.
Thanks again!



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

* Re: (goto-char ...) error
  2011-02-22 19:22       ` ken
@ 2011-02-22 19:45         ` Deniz Dogan
  2011-02-22 20:55           ` Drew Adams
  0 siblings, 1 reply; 10+ messages in thread
From: Deniz Dogan @ 2011-02-22 19:45 UTC (permalink / raw)
  To: gebser; +Cc: GNU Emacs List

2011/2/22 ken <gebser@mousecar.com>:
>
> On 02/22/2011 01:45 PM Deniz Dogan wrote:
>> 2011/2/22 ken <gebser@mousecar.com>:
>>> On 02/22/2011 12:31 PM Deniz Dogan wrote:
>>>> 2011/2/22 ken <gebser@mousecar.com>:
>>>>> ....
>>>>
>>> My understanding is that the 4th arg to re-search-forward is to repeat
>>> the search, so I set that to nil.
>>>
>>> I get the same error whether the 3rd arg is t or nil (!?):
>>>
>>> (setq ptname (re-search-forward "REGEXP" endpt t nil))
>>>      (if ptname
>>>          ((goto-char (- ptname 1))
>>>           ....
>>>
>>> The error line in *Messages* says:
>>>
>>> if: Invalid function: (goto-char (- begin-name-value 1))
>>>
>>>
>>
>> You have one pair of parentheses too many.
>>
>> Change:
>>
>> ((goto-char (- ptname 1))
>>
>> to:
>>
>> (goto-char (- ptname 1))
>>
>> The error is telling you that "(goto-char (- ptname 1))" is an invalid
>> function, which could potentially be confusing, but it really makes
>> sense.  You call a function named `foo' like (foo ...), but if you do
>> "((foo ...))" you're trying to call a function named "(foo ...)" which
>> is not a valid function.
>>
>> From the documentation of `if':
>>
>> (if COND THEN ELSE...)
>> If COND yields non-nil, do THEN, else do ELSE...
>>
>> This means that your THEN clause must be a single expression.
>> Everything starting with the third argument to `if' is considered part
>> of the ELSE clause.
>>
>> If you want to multiple expressions in the THEN clause, use `progn' as
>> such:
>>
>> (if (= x y)
>>     (progn
>>       (message "They're equal")
>>       (message "Hooray!"))
>>   (message "They're not equal.")
>>   (message "Too bad, bro."))
>>
>> I hope that helps!
>
> Yeah, I think it should.  Thanks.
>
> Just to be clear about one more thing I'll be addressing subsequently,
> i.e., another "if" nested inside the first:
>
> (if (= x y)
>   (progn
>     (message "They're equal")
>     (message "Hooray!")
>     (if (= x z)
>          (progn
>            (message "The next one's equal too.")
>            (message "Hooray++!")))) ; enuf )s to match up to 1st progn
>  (message "They're not equal.")
>  (message "Too bad, bro."))
>

This is fine, but when you don't need the ELSE clause, it's usually
better to use `when', which is like `if', except it doesn't have an
ELSE and you don't need to use `progn'.

(if (= x y)
    (progn
      (message "They're equal")
      (message "Hooray!")
      (when (= x z)
        (message "The next one's equal too.")
        (message "Hooray++!")))
  (message "They're not equal.")
  (message "Too bad, bro."))

There is also `unless' which you can use when you find yourself doing
"when (not (whatever))".

(unless (= x y)
  (message "OMG they differ!")
  (if (> x y)
      (message "OMG X BEATS Y!!!")
    (message "OMG Y BEATS X")))

I encourage you to read the Elisp manual which should come with your
Emacs.  Hit "C-h i d m Elisp RET" in Emacs.  What I told you just now
is covered in chapter 10 "(elisp) Control Structures".

-- 
Deniz Dogan



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

* RE: (goto-char ...) error
  2011-02-22 19:45         ` Deniz Dogan
@ 2011-02-22 20:55           ` Drew Adams
  0 siblings, 0 replies; 10+ messages in thread
From: Drew Adams @ 2011-02-22 20:55 UTC (permalink / raw)
  To: 'Deniz Dogan', gebser; +Cc: 'GNU Emacs List'

> This is fine, but when you don't need the ELSE clause, it's usually
> better to use `when', which is like `if', except it doesn't have an
> ELSE and you don't need to use `progn'.

FWIW - Some people, including me, use `when' and `unless' to indicate to human
readers that the return value is unimportant: only side effects are of interest.

To indicate (to humans) that the return value is used, I use `if', `and', `or',
`cond', or `case'.  That makes the code simpler to read, assuming I didn't lie
or make a mistake: Whenever you see `when' or `unless' you can forget about the
return value; whenever you see `if', `and', or `or' you know the return value is
probably used in some way.

Other people, including those who maintain Emacs, apparently do not follow this
convention for the most part.  I have no idea how widespread the convention is.
I picked it up long ago when using Common Lisp.

"Common Lisp The Language" says this (at least in my 1984 copy, now far out of
date), for example:

"As a matter of style, `when' is normally used to conditionally produce some
side effects, and the value of the `when'-form is normally not used.  If the
value is relevant, then it may be stylistically more appropriate to use `and' or
`if'."




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

* Re: (goto-char ...) error
       [not found] <mailman.3.1298393577.375.help-gnu-emacs@gnu.org>
@ 2011-02-22 22:15 ` Tim X
  0 siblings, 0 replies; 10+ messages in thread
From: Tim X @ 2011-02-22 22:15 UTC (permalink / raw)
  To: help-gnu-emacs

ken <gebser@mousecar.com> writes:

> Performing one search, I save the result with
>
> (setq ptname (re-search-forward ...))
>
> Then I want to back up one character and perform another search, so I do
>
> (goto-char (- ptname 1))
>
> But this pukes an error.  What's unkosher here?
>

Could be almost anything - without the error message it is all just
guesswork. Some things to consider 

1. What is the value of ptname if the re-search-forward fails?
2. What is the result of goto-char if ptname is nil or equal to
(point-min)?

Tim


-- 
tcross (at) rapttech dot com dot au


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

* Re: (goto-char ...) error
       [not found]   ` <mailman.11.1298399070.22047.help-gnu-emacs@gnu.org>
@ 2011-02-22 22:27     ` Tim X
  0 siblings, 0 replies; 10+ messages in thread
From: Tim X @ 2011-02-22 22:27 UTC (permalink / raw)
  To: help-gnu-emacs

ken <gebser@mousecar.com> writes:

> On 02/22/2011 12:31 PM Deniz Dogan wrote:
>> 2011/2/22 ken <gebser@mousecar.com>:
>>> Performing one search, I save the result with
>>>
>>> (setq ptname (re-search-forward ...))
>>>
>>> Then I want to back up one character and perform another search, so I do
>>>
>>> (goto-char (- ptname 1))
>>>
>>> But this pukes an error.  What's unkosher here?
>>>
>> 
>> It's much easier if you tell us what the error is.
>> 
>> I tried to reproduce the problem using this code:
>> 
>> ;; search for "a"
>> (let ((ptname (re-search-forward "a" nil t)))
>>   (when ptname
>>     (goto-char (- ptname 1))))
>> 
>> It all depends on how you use re-search-forward. As you can see in my
>> example, I pass t as the third argument meaning "don't error if you
>> can't find it, just return nil". I then make sure that ptname is
>> non-nil before I try to act on it using `-', otherwise we would be
>> doing (- nil 1) which makes no sense.
>> 
>
> My understanding is that the 4th arg to re-search-forward is to repeat
> the search, so I set that to nil.
>
> I get the same error whether the 3rd arg is t or nil (!?):
>
> (setq ptname (re-search-forward "REGEXP" endpt t nil))
>       (if ptname
> 	  ((goto-char (- ptname 1))
>            ....
>
> The error line in *Messages* says:
>
> if: Invalid function: (goto-char (- begin-name-value 1))
>

You probably don't need the ptname because re-search-forward sets point
and you can always get the value from the variable match-beginning

(when (re-search-forward "REGEXP" limit t)
      (goto-char (max (1- (point))
                      (point-min)))
      .....)

Note also that there is no need to put a 'nil' for the last optional
argument - if you don't provide a value, it will default to nil.

Tim

-- 
tcross (at) rapttech dot com dot au


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

* Re: (goto-char ...) error
       [not found]       ` <mailman.1.1298402588.16069.help-gnu-emacs@gnu.org>
@ 2011-02-22 22:50         ` Tim X
  0 siblings, 0 replies; 10+ messages in thread
From: Tim X @ 2011-02-22 22:50 UTC (permalink / raw)
  To: help-gnu-emacs

ken <gebser@mousecar.com> writes:

> On 02/22/2011 01:45 PM Deniz Dogan wrote:
>> 2011/2/22 ken <gebser@mousecar.com>:
>>> On 02/22/2011 12:31 PM Deniz Dogan wrote:
>>>> 2011/2/22 ken <gebser@mousecar.com>:
>>>>> ....
>>>>
>>> My understanding is that the 4th arg to re-search-forward is to repeat
>>> the search, so I set that to nil.
>>>
>>> I get the same error whether the 3rd arg is t or nil (!?):
>>>
>>> (setq ptname (re-search-forward "REGEXP" endpt t nil))
>>>      (if ptname
>>>          ((goto-char (- ptname 1))
>>>           ....
>>>
>>> The error line in *Messages* says:
>>>
>>> if: Invalid function: (goto-char (- begin-name-value 1))
>>>
>>>
>> 
>> You have one pair of parentheses too many.
>> 
>> Change:
>> 
>> ((goto-char (- ptname 1))
>> 
>> to:
>> 
>> (goto-char (- ptname 1))
>> 
>> The error is telling you that "(goto-char (- ptname 1))" is an invalid
>> function, which could potentially be confusing, but it really makes
>> sense.  You call a function named `foo' like (foo ...), but if you do
>> "((foo ...))" you're trying to call a function named "(foo ...)" which
>> is not a valid function.
>> 
>> From the documentation of `if':
>> 
>> (if COND THEN ELSE...)
>> If COND yields non-nil, do THEN, else do ELSE...
>> 
>> This means that your THEN clause must be a single expression.
>> Everything starting with the third argument to `if' is considered part
>> of the ELSE clause.
>> 
>> If you want to multiple expressions in the THEN clause, use `progn' as
>> such:
>> 
>> (if (= x y)
>>     (progn
>>       (message "They're equal")
>>       (message "Hooray!"))
>>   (message "They're not equal.")
>>   (message "Too bad, bro."))
>> 
>> I hope that helps!
>
> Yeah, I think it should.  Thanks.
>
> Just to be clear about one more thing I'll be addressing subsequently,
> i.e., another "if" nested inside the first:
>
> (if (= x y)
>    (progn
>      (message "They're equal")
>      (message "Hooray!")
>      (if (= x z)
>           (progn
>             (message "The next one's equal too.")
>             (message "Hooray++!")))) ; enuf )s to match up to 1st progn
>  (message "They're not equal.")
>  (message "Too bad, bro."))
>
>
> elisp is weird.

When you need to use progn in your if statement, it is a sign you are
using the wrong construct or you need to reverse things. Although things
may seem weird, once you know the alternatives, you will likely find it
much clearer. 

1. if statements allow multiple forms in the else part, so reversing
your test means you can get rid of the progn statements. 

(if (not (= x y))
       (message "They're not equal. Too bad, bro.")
    (message "They're equal Horay!")
    (if (not (= x z))
         (message "The next one is not equal though")
      (message "The next one is equal as well. Hooray!")))

However, sometimes, this is not a good solution because it inverts the
way you think about the test and causes another layer of indirection. In
that case, one of the following may be more appropriate -

2. If you don't really need 'else' clauses, then the when or unless
statement is a better choice as it allows multiple forms i.e.

(when (= x y)
      (message "They match")
      (if (= x z)
          (message "The next ones match too")))

(unless (= x y)
        (message "They don't match")
        (do-some-stuff)
        ....)

3. If you need conditional branches, then cond is a good choice

(cond ((= x y)
       (message "y matches")
       (do-some-things)
       (do-some-more-things)
       (if (= x z)
           (message "z matches")))
     ((= x b)
      (message "b matches")
      (do-some-stuff)
      ...)
    (t (message "No match)))

Use the construct which makes your intention clear. Lots of nested if's
or progn's indicate there is probably a better form to express what you
mean. Of course, these are just rules of thumb - sometimes it makes
sense to use nested ifs and sometimes it makes sense to use progn (just
like sometimes code is clearer with a goto). Often, cluttered/unclear
code is really an indicaiton of a cluttered/unclear solution - this is
normal as you really only get to understand the problem when you try to
solve it. This is why refactoring is so important - as your
understanding of the probolem increases, your ability to express the
solution in a clear and concise form will also increase. If you can't
make the code clear, then you probably don't understand the problem yet.

Tim
-- 
tcross (at) rapttech dot com dot au


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

end of thread, other threads:[~2011-02-22 22:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <mailman.3.1298393577.375.help-gnu-emacs@gnu.org>
2011-02-22 22:15 ` (goto-char ...) error Tim X
2011-02-22 16:47 ken
2011-02-22 17:31 ` Deniz Dogan
2011-02-22 18:24   ` ken
2011-02-22 18:45     ` Deniz Dogan
2011-02-22 19:22       ` ken
2011-02-22 19:45         ` Deniz Dogan
2011-02-22 20:55           ` Drew Adams
     [not found]       ` <mailman.1.1298402588.16069.help-gnu-emacs@gnu.org>
2011-02-22 22:50         ` Tim X
     [not found]   ` <mailman.11.1298399070.22047.help-gnu-emacs@gnu.org>
2011-02-22 22:27     ` Tim X

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.