emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Eric Schulte <schulte.eric@gmail.com>
To: Alan Schmitt <alan.schmitt@polytechnique.org>
Cc: emacs-org list <emacs-orgmode@gnu.org>
Subject: Re: input data for babel blocks
Date: Mon, 30 Sep 2013 18:04:17 -0600	[thread overview]
Message-ID: <87siwlrgun.fsf@gmail.com> (raw)
In-Reply-To: m2ioxicw2i.fsf@polytechnique.org

Alan Schmitt <alan.schmitt@polytechnique.org> writes:

> Hello,
>
> In my quest for analyzing my data in org mode tables, I'm trying to see
> if I can use my favorite language (i.e., ocaml). I'm thus looking at how
> to input such tables in a caml program. I found that the following works
> well:
>
> --8<---------------cut here---------------start------------->8---
> #+name: data
> | 12 |
> | 42 |
>
> #+BEGIN_SRC ocaml :var x=data
> x
> #+END_SRC
>
> #+RESULTS:
> : - : int array array = [|[|12|]; [|42|]|]
> --8<---------------cut here---------------end--------------->8---
>
> (The only "bad" thing is that a single value is an array, but this is
> probably related to the following thing.) Unfortunately (for interaction
> with org mode), caml is strongly typed, and arrays must be
> homogeneous. Thus the following fails:
>
> --8<---------------cut here---------------start------------->8---
> #+name: myinput
> | x | 12 |
> | y | 24 |
>
> #+BEGIN_SRC ocaml :var x=myinput
> x
> #+END_SRC
> --8<---------------cut here---------------end--------------->8---
>
> with the error in the toplevel:
>
> --8<---------------cut here---------------start------------->8---
> # let x = [|[|"x"; 12|]; [|"y"; 24|]|];;
> x;;
> "org-babel-ocaml-eoe";;
> Characters 17-19:
>   let x = [|[|"x"; 12|]; [|"y"; 24|]|];;
>                    ^^
> Error: This expression has type int but an expression was expected of type
>          string
> --8<---------------cut here---------------end--------------->8---
>
> I would like to change the parsing of table in ob-ocaml so that it
> generates an array of _tuples_, for instance for the previous example:
>
> #+BEGIN_SRC ocaml
> let x = [| ("x", 12); ("y", 24) |];;
> #+END_SRC
>
> I looked at the code, and this seems to be the relevant part:
>
> #+BEGIN_SRC emacs-lisp
> (defun org-babel-variable-assignments:ocaml (params)
>   "Return list of ocaml statements assigning the block's variables."
>   (mapcar
>    (lambda (pair) (format "let %s = %s;;" (car pair)
> 			  (org-babel-ocaml-elisp-to-ocaml (cdr pair))))
>    (mapcar #'cdr (org-babel-get-header params :var))))
>
> (defun org-babel-ocaml-elisp-to-ocaml (val)
>   "Return a string of ocaml code which evaluates to VAL."
>   (if (listp val)
>       (concat "[|" (mapconcat #'org-babel-ocaml-elisp-to-ocaml val "; ") "|]")
>     (format "%S" val)))
> #+END_SRC
>
> I tried tweaking this to the following:
>
> #+BEGIN_SRC emacs-lisp
> (defun org-babel-variable-assignments:ocaml (params)
>   "Return list of ocaml statements assigning the block's variables."
>   (mapcar
>    (lambda (pair) (format "let %s = %s;;" (car pair)
> 			  (org-babel-ocaml-elisp-to-ocaml (cdr pair))))
>    (mapcar #'cdr (org-babel-get-header params :var))))
>
> (defun org-babel-ocaml-elisp-to-ocaml (val)
>   "Return a string of ocaml code which evaluates to VAL."
>   (if (listp val)
>       (concat "[|" (mapconcat #'org-babel-ocaml-elisp-to-ocaml-tuple val "; ") "|]")
>     (format "%S" val)))
>
> (defun org-babel-ocaml-elisp-to-ocaml-tuple (val)
>   "Return a string of ocaml code which evaluates to VAL, as a tuple."
>   (if (listp val)
>       (concat "(" (mapconcat #'org-babel-ocaml-elisp-to-ocaml-tuple val ", ") ")")
>     (format "%S" val)))
> #+END_SRC
>
> Now the example seems to work:
>
> --8<---------------cut here---------------start------------->8---
> #+name: myinput
> | x | 12 |
> | y | 24 |
>
> #+BEGIN_SRC ocaml :var x=myinput
> x
> #+END_SRC
>
> #+RESULTS:
> : - : (string * int) array = [|("x", 12); ("y", 24)|]
> --8<---------------cut here---------------end--------------->8---
>
> (and the previous example is even nicer:
> --8<---------------cut here---------------start------------->8---
> #+name: data
> | 12 |
> | 42 |
>
> #+BEGIN_SRC ocaml :var x=data
> x
> #+END_SRC
>
> #+RESULTS:
> : - : int array = [|12; 42|]
> --8<---------------cut here---------------end--------------->8---
> )
>
> I have the following questions for the list:
> - can I always assume that tables are passed as lists of lists?

Currently this is the default behavior in (I believe) every language.

> 
> - would the patch above be a useful way to deal with this?

My problem with the patch above is that it makes OCaml different from
every other language (especially ob-haskell which has similar type
restraints), and that it doesn't work for tables with different
alignment, e.g.,

| x | y |
| 0 | 1 |

I guess one possible "correct" solution would be to use a variant type
with something like the following.

    type orgCell =
      | Int of int
      | Float of float
      | String of string

> - is there a way to specify the :var parsing in a code block or in the
> table?
>

Currently there is not.  Perhaps there is an elegant solution using a
new header argument to control how values are represented in literal
source code.

This is an interesting question.  I'm not sure what is best here, but
ideally any solution will generalize to other strongly typed languages,
will support all possible tables, and will work simply for simple tables
allowing users to use tables without having to jump through typed hoops.

Cheers,

>
> Thanks,
>
> Alan
>

-- 
Eric Schulte
https://cs.unm.edu/~eschulte
PGP: 0x614CA05D

  parent reply	other threads:[~2013-10-01  0:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-30 12:50 input data for babel blocks Alan Schmitt
2013-09-30 16:26 ` Charles Berry
2013-10-01  0:08   ` Eric Schulte
2013-10-01  8:12   ` Alan Schmitt
2013-10-01 11:58     ` Eric Schulte
2013-10-01 13:01       ` Alan Schmitt
2013-10-01 14:29         ` Rick Frankel
2013-10-01 15:16           ` Alan Schmitt
2013-10-01 15:29     ` Charles Berry
2013-10-01 17:16       ` Alan Schmitt
2013-10-01 19:06       ` Thomas S. Dye
2013-10-01  0:04 ` Eric Schulte [this message]
2013-10-01  8:15   ` Alan Schmitt

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=87siwlrgun.fsf@gmail.com \
    --to=schulte.eric@gmail.com \
    --cc=alan.schmitt@polytechnique.org \
    --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).