From mboxrd@z Thu Jan 1 00:00:00 1970 From: "Eric Schulte" Subject: Re: [Babel] Interpreting results as tables and (eval)'uation of them Date: Mon, 14 Feb 2011 11:58:27 -0700 Message-ID: <871v3av2tg.fsf@gmail.com> References: <1297629465.4235.27.camel@eeevk> Mime-Version: 1.0 Content-Type: text/plain Return-path: Received: from [140.186.70.92] (port=37096 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Pp40W-0006rB-4m for emacs-orgmode@gnu.org; Mon, 14 Feb 2011 14:22:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Pp40U-0006BW-QZ for emacs-orgmode@gnu.org; Mon, 14 Feb 2011 14:22:47 -0500 Received: from mail-yx0-f169.google.com ([209.85.213.169]:58034) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Pp40U-0006BJ-LF for emacs-orgmode@gnu.org; Mon, 14 Feb 2011 14:22:46 -0500 Received: by yxl31 with SMTP id 31so2491135yxl.0 for ; Mon, 14 Feb 2011 11:22:42 -0800 (PST) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: danamlund@gmail.com Cc: emacs-orgmode@gnu.org Hi Dan, Dan Amlund Thomsen 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 > printf("(1 2)"); > #+end_src > > Returns the error "Invalid function: 1". > > The correct approach is: > #+begin_src c++ :includes > 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 > 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