all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Return value not as expected in Emacs Lisp function
@ 2013-08-07 18:48 Thorsten Jolitz
  2013-08-07 21:00 ` Stefan Monnier
  2013-08-07 21:07 ` Pascal J. Bourguignon
  0 siblings, 2 replies; 7+ messages in thread
From: Thorsten Jolitz @ 2013-08-07 18:48 UTC (permalink / raw)
  To: help-gnu-emacs


Hi List, 

I have a hard time to understand the following behaviour of an Emacs Lisp
program of mine. Here is an abstract version of this program:

#+begin_src emacs-lisp
  (defun my-fun ()
    (let ((result (concat
                    "(prog "
                    (mapconcat
                     (lambda ...)
                     lst "")
                    ")")))
      (message "%s" result) ; just for logging
      result))
#+end_src

After running the program, I find, as expected, something like this in
the *Messages* buffer:

#+begin_quote
(prog (click NIL 1)(press NIL 1)(click NIL 4)(click NIL 1))
#+end_quote

so the value of 'result' is just fine in the second-last line of the
fun.

But the return value is not what I would expect

#+begin_src emacs-lisp
 (print (my-fun))
#+end_src

or 

#+begin_src emacs-lisp
 (message "%s" (my-fun))
#+end_src

yield

#+begin_quote
(prog )
#+end_quote

and I ask myself what happened between the second-last and the last line of
the function? I cannot reproduce this with a MWE, and the real function is too
convoluted to present it here, so I keep the problem description on an
abstract level. 

I'm actually only interested in the result string as a return value, the
message statement is just for logging. But why is the string produced by
'mapconcat' missing in the return value?

-- 
cheers,
Thorsten




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-07 18:48 Return value not as expected in Emacs Lisp function Thorsten Jolitz
@ 2013-08-07 21:00 ` Stefan Monnier
  2013-08-07 22:47   ` Thorsten Jolitz
  2013-08-07 21:07 ` Pascal J. Bourguignon
  1 sibling, 1 reply; 7+ messages in thread
From: Stefan Monnier @ 2013-08-07 21:00 UTC (permalink / raw)
  To: help-gnu-emacs

> so the value of 'result' is just fine in the second-last line of the
> fun.

> But the return value is not what I would expect

Maybe there's something going on in the way you "get the return value".
IOW give us more details to reproduce the problem.


        Stefan




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-07 18:48 Return value not as expected in Emacs Lisp function Thorsten Jolitz
  2013-08-07 21:00 ` Stefan Monnier
@ 2013-08-07 21:07 ` Pascal J. Bourguignon
  2013-08-07 22:54   ` Thorsten Jolitz
  1 sibling, 1 reply; 7+ messages in thread
From: Pascal J. Bourguignon @ 2013-08-07 21:07 UTC (permalink / raw)
  To: help-gnu-emacs

Thorsten Jolitz <tjolitz@gmail.com> writes:

> and I ask myself what happened between the second-last and the last line of
> the function? I cannot reproduce this with a MWE, and the real function is too
> convoluted to present it here, so I keep the problem description on an
> abstract level. 

On an abstract leve, I can't debug a function if I don't have it's
code.  That's the reason d'être of the MWE, and by default the real code.


> I'm actually only interested in the result string as a return value, the
> message statement is just for logging. But why is the string produced by
> 'mapconcat' missing in the return value?

The real question is why you use mapconcat to produce a string
representation of a sexp?  Just use prin1-to-string!

(let ((list '((click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))))
  (prin1-to-string `(prog ,@list )))
--> "(prog (click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))" 

Notice:

- emacs lisp is a lisp-2, not a lst-1.

- NIL is true:
  
  (not (not 'NIL))       --> t
  (not 'NIL)             --> nil
  (if 'NIL 'true 'false) --> true


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.  
You know you've been lisping too long when you see a recent picture of George 
Lucas and think "Wait, I thought John McCarthy was dead!" -- Dalek_Baldwin




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-07 21:00 ` Stefan Monnier
@ 2013-08-07 22:47   ` Thorsten Jolitz
  0 siblings, 0 replies; 7+ messages in thread
From: Thorsten Jolitz @ 2013-08-07 22:47 UTC (permalink / raw)
  To: help-gnu-emacs

Stefan Monnier <monnier@iro.umontreal.ca> writes:

>> so the value of 'result' is just fine in the second-last line of the
>> fun.
>
>> But the return value is not what I would expect
>
> Maybe there's something going on in the way you "get the return value".
> IOW give us more details to reproduce the problem.

While preparing to post the real function definition, I found the error:
a missing opening parenthesis in the (interactive...) part of the
function, in a branch of a (cond...) statement I never tested.

In total, the parens matched - but not all in the right places. 

Sorry for the noise.

-- 
cheers,
Thorsten




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-07 21:07 ` Pascal J. Bourguignon
@ 2013-08-07 22:54   ` Thorsten Jolitz
  2013-08-08 22:31     ` Pascal J. Bourguignon
  0 siblings, 1 reply; 7+ messages in thread
From: Thorsten Jolitz @ 2013-08-07 22:54 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>> and I ask myself what happened between the second-last and the last line of
>> the function? I cannot reproduce this with a MWE, and the real function is too
>> convoluted to present it here, so I keep the problem description on an
>> abstract level. 
>
> On an abstract leve, I can't debug a function if I don't have it's
> code.  That's the reason d'être of the MWE, and by default the real code.

I found the error, a misplaced paren. I could not reproduce the error in
a MWE - probably I did not copy the part with the misplaced paren to the
MWE.

>> I'm actually only interested in the result string as a return value, the
>> message statement is just for logging. But why is the string produced by
>> 'mapconcat' missing in the return value?
>
> The real question is why you use mapconcat to produce a string
> representation of a sexp?  Just use prin1-to-string!
>
> (let ((list '((click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))))
>   (prin1-to-string `(prog ,@list )))
> --> "(prog (click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))" 
>
> Notice:
>
> - emacs lisp is a lisp-2, not a lst-1.
>
> - NIL is true:
>   
>   (not (not 'NIL))       --> t
>   (not 'NIL)             --> nil
>   (if 'NIL 'true 'false) --> true


I should have said that this 

,-----------------------------------------------------------------
| "(prog (click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))"
`-----------------------------------------------------------------

is actually PicoLisp, a lisp-1 with NIL and T syntax (uppercase!). I
thought the 'prog in the beginning (PicoLisp's 'progn)  would make it
clear its not Elisp. At least C-h f doesn' show me a 'prog function in
Elisp. 

But thanks for your answer, I did not know `prin1-to-string', and finally
looked up the difference between lisp-1 and lisp-2. 

-- 
cheers,
Thorsten




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-07 22:54   ` Thorsten Jolitz
@ 2013-08-08 22:31     ` Pascal J. Bourguignon
  2013-08-09 12:03       ` Thorsten Jolitz
  0 siblings, 1 reply; 7+ messages in thread
From: Pascal J. Bourguignon @ 2013-08-08 22:31 UTC (permalink / raw)
  To: help-gnu-emacs

Thorsten Jolitz <tjolitz@gmail.com> writes:

> ,-----------------------------------------------------------------
> | "(prog (click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))"
> `-----------------------------------------------------------------
>
> is actually PicoLisp, a lisp-1 with NIL and T syntax (uppercase!). I
> thought the 'prog in the beginning (PicoLisp's 'progn)  would make it
> clear its not Elisp. At least C-h f doesn' show me a 'prog function in
> Elisp. 
>
> But thanks for your answer, I did not know `prin1-to-string', and finally
> looked up the difference between lisp-1 and lisp-2. 

Ok, that explains the 'lst.

Now, emacs has one good characteristic that helps in manipilating sexps
from other lisps:  it has no module or package system and it has case
sensitive symbols, with no lisp reader to upcase them automatically by
default.

Therefore, you can perfectly manipulate picolisp sexps as emacs lisp
sexps.  Unless you have to deal with reader macros or other strange
syntaxes, my advice would be to stick to sexps, this has big advantages
over strings.


As for the misplaced parenthesis problem, be sure to let emacs
auto-indent lisp (any) code for you, selectnig a region and typing C-M-\
(indent-region), or using paredit (strongly advised, to edit any kind of
sexps), typing M-q (paredit-reindent-defun) from time to time inside
sexps.

Then you will be shocked by any misplaced parenthesis, since it will
imply very strange indentation, like this:


(defun hostname ()
  (interactive "Hello"
               (cond ((boundp  'system-name) system-name)
                     ((fboundp 'system-name) (system-name)))
               (t (shell-command-to-string
                   "echo -n $( (hostname -f 2>/dev/null) || (hostname 2>/dev/null) )"))))

where it is obvious that there's a missing closing parenthesis for
interactive, and that the cond is closed too early (before the (t …)
branch.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
A bad day in () is better than a good day in {}.  
You know you've been lisping too long when you see a recent picture of George 
Lucas and think "Wait, I thought John McCarthy was dead!" -- Dalek_Baldwin




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

* Re: Return value not as expected in Emacs Lisp function
  2013-08-08 22:31     ` Pascal J. Bourguignon
@ 2013-08-09 12:03       ` Thorsten Jolitz
  0 siblings, 0 replies; 7+ messages in thread
From: Thorsten Jolitz @ 2013-08-09 12:03 UTC (permalink / raw)
  To: help-gnu-emacs

"Pascal J. Bourguignon" <pjb@informatimago.com> writes:

> Thorsten Jolitz <tjolitz@gmail.com> writes:
>
>> ,-----------------------------------------------------------------
>> | "(prog (click NIL 1) (press NIL 1) (click NIL 4) (click NIL 1))"
>> `-----------------------------------------------------------------
>>
>> is actually PicoLisp, a lisp-1 with NIL and T syntax (uppercase!). I
>> thought the 'prog in the beginning (PicoLisp's 'progn)  would make it
>> clear its not Elisp. At least C-h f doesn' show me a 'prog function in
>> Elisp. 
>>
>> But thanks for your answer, I did not know `prin1-to-string', and finally
>> looked up the difference between lisp-1 and lisp-2. 
>
> Ok, that explains the 'lst.
>
> Now, emacs has one good characteristic that helps in manipilating sexps
> from other lisps:  it has no module or package system and it has case
> sensitive symbols, with no lisp reader to upcase them automatically by
> default.
>
> Therefore, you can perfectly manipulate picolisp sexps as emacs lisp
> sexps.  Unless you have to deal with reader macros or other strange
> syntaxes, my advice would be to stick to sexps, this has big advantages
> over strings.

But isn't the communication between the two lisps (picolisp and elisp)
always done with strings? It `comint-send-string' or
`process-send-string', no matter if that string contains a sexp or
something else. Of course, both lisps can then "read-from-string" the
sexps they recieve from the other program if the syntax matches, but
they are send and arrive as strings - right?

> As for the misplaced parenthesis problem, be sure to let emacs
> auto-indent lisp (any) code for you, selectnig a region and typing C-M-\
> (indent-region), or using paredit (strongly advised, to edit any kind of
> sexps), typing M-q (paredit-reindent-defun) from time to time inside
> sexps.
>
> Then you will be shocked by any misplaced parenthesis, since it will
> imply very strange indentation, like this:
>
>
> (defun hostname ()
>   (interactive "Hello"
>                (cond ((boundp  'system-name) system-name)
>                      ((fboundp 'system-name) (system-name)))
>                (t (shell-command-to-string
>                    "echo -n $( (hostname -f 2>/dev/null) || (hostname 2>/dev/null) )"))))
>
> where it is obvious that there's a missing closing parenthesis for
> interactive, and that the cond is closed too early (before the (t …)
> branch.

ok, thx for the tip. 

-- 
cheers,
Thorsten




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

end of thread, other threads:[~2013-08-09 12:03 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-08-07 18:48 Return value not as expected in Emacs Lisp function Thorsten Jolitz
2013-08-07 21:00 ` Stefan Monnier
2013-08-07 22:47   ` Thorsten Jolitz
2013-08-07 21:07 ` Pascal J. Bourguignon
2013-08-07 22:54   ` Thorsten Jolitz
2013-08-08 22:31     ` Pascal J. Bourguignon
2013-08-09 12:03       ` Thorsten Jolitz

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.