* [Babel] Interpreting results as tables and (eval)'uation of them @ 2011-02-13 20:37 Dan Amlund Thomsen 2011-02-14 18:58 ` Eric Schulte 0 siblings, 1 reply; 3+ messages in thread From: Dan Amlund Thomsen @ 2011-02-13 20:37 UTC (permalink / raw) To: emacs-orgmode 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 | * 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 | * 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: "#" 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)" ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Babel] Interpreting results as tables and (eval)'uation of them 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 0 siblings, 1 reply; 3+ messages in thread From: Eric Schulte @ 2011-02-14 18:58 UTC (permalink / raw) To: danamlund; +Cc: emacs-orgmode 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 ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Babel] Interpreting results as tables and (eval)'uation of them 2011-02-14 18:58 ` Eric Schulte @ 2011-03-06 17:59 ` Eric Schulte 0 siblings, 0 replies; 3+ messages in thread From: Eric Schulte @ 2011-03-06 17:59 UTC (permalink / raw) To: danamlund; +Cc: emacs-orgmode 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 ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-03-06 17:59 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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
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).