emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: "Eric Schulte" <schulte.eric@gmail.com>
To: danamlund@gmail.com
Cc: emacs-orgmode@gnu.org
Subject: Re: [Babel] Interpreting results as tables and (eval)'uation of them
Date: Sun, 06 Mar 2011 10:59:31 -0700	[thread overview]
Message-ID: <87lj0sgmf0.fsf@gmail.com> (raw)
In-Reply-To: <871v3av2tg.fsf@gmail.com> (Eric Schulte's message of "Mon, 14 Feb 2011 11:58:27 -0700")

Hi,

Just to update, two of the three problems mentioned in this thread have
now been fixed.  The two global issues (i.e. 2. and 3.), meaning that if
the results are not a well formed list, or are not eval-able, then they
are returned literally, allowing things like passing tuples back from
python etc...

The remaining issue (":results output" → ":results scalar") is a
language implementation specific issue, and will have to be fixed in
those languages in which is occurs.

Best -- Eric

Note: that results may still be eval'd, e.g.,

#+begin_src python :results value
  return "[1, 2]"
#+end_src

#+results:
| 1 | 2 |

and

#+begin_src python :results value
  return [1, 2]
#+end_src

#+results:
| 1 | 2 |

There is no way to differentiate between the two code blocks above in a
general way, however something like the following may be used to force a
string interpretation (note: I don't know python so there's probably a
better way).

#+begin_src python :results value
  return "%r" % "[1 2]"
#+end_src

#+results:
: [1 2]

Maybe this behavior should be changed, but I'm not sure how...

A perhaps slightly more unsettling version of the above would be
#+begin_src python :results value
  return "(mapcar (lambda (el) (+ 1 el)) '(1 2))"
#+end_src

#+results:
| 2 | 3 |

"Eric Schulte" <schulte.eric@gmail.com> writes:

> Hi Dan,
>
> Dan Amlund Thomsen <danamlund@gmail.com> writes:
>
>> I've encountered some weird, possible buggy, behavior when
>> interpreting results as tables (tested with python, scheme and lisp).
>>
>> * Item 1: Interpreting result as table
>> With ":results value" the result is interpreted as a table if
>> possible, but with ":results output" it isn't. This happens with
>> python, lisp and scheme, but not with c.
>>
>> The documentation suggests both value and output results should be
>> interpreted as a table if possible.
>>
>> "By default, results are inserted as either a table or scalar
>> depending on their value." [http://orgmode.org/manual/results.html]
>>
>> #+begin_src python :results output
>>   print "'(1 2)"
>> #+end_src
>>
>> #+results:
>> : '(1 2)
>>
>> #+begin_src python :results value
>>   return "'(1 2)"
>> #+end_src
>>
>> #+results:
>> | 1 | 2 |
>>
>
> Yes, this assumption (":results output" implies ":results scalar") is
> built into many of the language-specific modes and should probably be
> removed.
>
>>
>> * Item 2: Evaluating list results
>> When a result is interpreted as a list, the list is (eval)'ed. This
>> happens in non-lisp languages (c, python) but not in lisp languages
>> (lisp, scheme).
>>
>> In my opinion the lists should not be evaluated, but
>> 'org-babel-script-escape' and 'org-babel-read' suggests it is intended
>> behavior.
>>
>> Is this a bug or a feature?
>>
>> #+begin_src c++ :includes <stdio.h>
>>   printf("(1 2)");
>> #+end_src
>>
>> Returns the error "Invalid function: 1".
>>
>> The correct approach is:
>> #+begin_src c++ :includes <stdio.h>
>>   printf("(list 1 2)");
>> #+end_src
>>
>> #+results:
>> | 1 | 2 |
>>
>> With lisp the list is not evaluated (note that "'(1 2)" results in
>> "(1 2)").
>> #+begin_src lisp
>>   '(1 2)
>> #+end_src
>>
>> #+results:
>> | 1 | 2 |
>>
>
> Hmm, I'll have to take a closer look at `org-babel-script-escape'.
> Automatic evaluation of lispy return strings should not be the default
> behavior as I doubt that is what users would expect.  Maybe we shouldn't
> be calling `org-babel-read' (which *is* supposed to evaluate lispy
> strings) from `org-babel-script-escape'.  Thanks for pointing this out.
>
>>
>> * Item 3: Checking if result is a list is not safe
>> Mismatched parenthesis and bad characters causes errors. I suggest
>> showing the raw result if the result is not a valid list.
>>
>> I'm not sure if this is a bug or not. These error messages could be
>> helpful in debugging code when trying to output a list that needs to
>> be evaluated. Although the final output of the (invalid) list could
>> also be helpful with debugging.
>>
>> #+begin_src c++ :includes <stdio.h>
>>   printf("(");
>> #+end_src
>> Returns the error: End of file during parsing
>>
>> #+begin_src python 
>>   return "(list #)"
>> #+end_src
>> Returns the error: Invalid read syntax: "#"
>>
>
> Agreed, in these cases the raw scalar result should be returned.  Again,
> thanks for pointing these out.
>
>>
>> Here are some possible solutions:
>> #+begin_src emacs-lisp
>>   (defun org-babel-safe-read-dont-eval (str)
>>     "Converts string into a list. Elements are converted into
>>   strings to prevent read errors from special characters."
>>     (let ((str (replace-regexp-in-string
>>                 "\\([^() \f\t\n\r\v]+\\)" "\"\\1\""str)))
>>       (condition-case nil
>>           (read str)
>>         (error (concat "\"" str "\"")))))
>>
>>   (org-babel-safe-read-dont-eval "(1 1#123 1)")  
>> #+end_src
>>
>> #+results:
>> | 1 | 1#123 | 1 |
>>
>> #+begin_src emacs-lisp
>>   (defun org-babel-safe-read-do-eval (str)
>>     "Converts string into a evaluated list."
>>     (condition-case nil
>>         (eval (read str))
>>       (error (concat "\"" str "\""))))
>>
>>   (org-babel-safe-read-do-eval "(1 1#123 1)")
>> #+end_src
>>
>> #+results:
>> : "(1 1#123 1)"
>>
>
> Yes, these code snippets seem to be headed in the right direction.
>
> Much appreciated -- Eric

      reply	other threads:[~2011-03-06 17:59 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-02-13 20:37 [Babel] Interpreting results as tables and (eval)'uation of them Dan Amlund Thomsen
2011-02-14 18:58 ` Eric Schulte
2011-03-06 17:59   ` Eric Schulte [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87lj0sgmf0.fsf@gmail.com \
    --to=schulte.eric@gmail.com \
    --cc=danamlund@gmail.com \
    --cc=emacs-orgmode@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.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).