3

I cannot understand the behavior of this simple code:

(defun foo (str bool)
  (interactive
    (list (read-string "Some text: ")
          (y-or-n-p "Yes or no? ")))
  (message "%s is first" str)
  (if bool (message "%s is in if" str)))

When I call it with M-x foo, it prompts for a string input -- which I give as this -- then Yes or no? Good so far. But if I type in n, it prints out this is first. But if I choose y, it seems to jump past the (message "%s is first" str) line and enter the if, which is true (not nil), printing this is in f. Why is the line before if... being skipped if I choose y?

7

Forms in the function body are executed in order, just as you would expect.

When you choose "y" if does not "jump" past the first message call. If looks like it did because the first message gets immediately replaced by the second one.

To check that this is true, open the *Messages* buffer and then do M-x foo. You will see that foo adds two messages to the bottom of this buffer, as expected.

You can also use edebug and step through your function to see what happens. To instrument a function for edebug, put the cursor somewhere inside the defun form and press C-u C-M-x.

  • What about the y/n? I learned that anything besides nil is considered true. So why does the if statement fail with n? Is n the same as nil? – 147pm Dec 12 '15 at 16:58
  • No, n is not the same as nil. The if condition is false when you answer "n" because the function y-or-n-p returns t if the user types y, nil if the user types n. (See the link to the manual.) – Constantine Dec 12 '15 at 17:07
3

It's not being skipped. The second message is printed after the first message is printed, but there is no wait between the two, so you do not notice the first message. Look in buffer *Messages* and you will see both messages.

To give the user time to see the first message, you can use sit-for or sleep-for after it:

(defun foo (str bool)
  (interactive (list (read-string "Some text: ")
               (y-or-n-p "Yes or no? ")))
  (message "%s is first" str)
  (sit-for 2)
  (when bool (message "%s is in if" str)))
  • Don't know who to check when both answers are same and equally helpful. . . – 147pm Dec 12 '15 at 17:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.