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: Sun, 06 Mar 2011 10:59:31 -0700 Message-ID: <87lj0sgmf0.fsf@gmail.com> References: <1297629465.4235.27.camel@eeevk> <871v3av2tg.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Return-path: Received: from [140.186.70.92] (port=49134 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PwIF5-0005Jb-1s for emacs-orgmode@gnu.org; Sun, 06 Mar 2011 12:59:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PwIF3-0001y6-H8 for emacs-orgmode@gnu.org; Sun, 06 Mar 2011 12:59:43 -0500 Received: from mail-gy0-f169.google.com ([209.85.160.169]:60465) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PwIF3-0001xv-DV for emacs-orgmode@gnu.org; Sun, 06 Mar 2011 12:59:41 -0500 Received: by gyb13 with SMTP id 13so1825413gyb.0 for ; Sun, 06 Mar 2011 09:59:40 -0800 (PST) In-Reply-To: <871v3av2tg.fsf@gmail.com> (Eric Schulte's message of "Mon, 14 Feb 2011 11:58:27 -0700") 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, 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" =E2=86=92 ":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" writes: > 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=20 >> 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)")=20=20 >> #+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