emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[O] Re: [Orgmode] [Babel] Interpreting results as tables and (eval)'uati


From: Eric Schulte
Subject: [O] Re: [Orgmode] [Babel] Interpreting results as tables and (eval)'uation of them
Date: Sun, 06 Mar 2011 10:59:31 -0700
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.50 (gnu/linux)

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" <address@hidden> writes:

> Hi Dan,
>
> Dan Amlund Thomsen <address@hidden> 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 via email to

[Prev in Thread] Current Thread [Next in Thread]