Browse Source

Merge branch 'master' into investigation

Conflicts:
	org-babel.org
Eric Schulte 16 years ago
parent
commit
68bd53cf7c
1 changed files with 253 additions and 168 deletions
  1. 253 168
      org-babel.org

+ 253 - 168
org-babel.org

@@ -208,174 +208,6 @@ would then be [[#sandbox][the sandbox]].
 
 
 
 
 * Tasks [35/57]
 * Tasks [35/57]
-** PROPOSED implement fully recursive evaluation machinery
-   The current parser / evaluator fails with greater levels of nested
-   function block calls (example below). If we want to overcome this I
-   think we'd have to redesign some of the evaluation
-   mechanism. Seeing as we are also facing issues like dealing with
-   default argument values, and seeing as we now know how we want the
-   library of babel to behave in addition to the source blocks, now
-   might be a good time to think about this. It would be nice to do
-   the full thing at some point, but otoh we may not consider it a
-   massive priority.
-   
-   AIui, there are two stages: (i) construct a parse tree, and (ii)
-   evaluate it and return the value at the root. In the parse tree
-   each node represents an unevaluated value (either a literal value
-   or a reference). Node v may have descendent nodes, which represent
-   values upon which node v's evaluation depends. Once that tree is
-   constructed, then we evaluate the nodes from the tips towards the
-   root (a post-order traversal).
-
-   [This would also provide a solution for concatenating the STDOUTs
-   of called blocks, which is a [[*allow%20output%20mode%20to%20return%20stdout%20as%20value][task below]]; we concatenate them in
-   whatever order the traversal is done in.]
-
-   In addition to the variable references (i.e. daughter nodes), each
-   node would contain the information needed to evaluate that node
-   (e.g. lang body). Then we would pass a function postorder over the
-   tree which would call o-b-execute-src-block at each node, finally
-   returning the value at the root.
-
-   Fwiw I made a very tentative small start at stubbing this out in
-   org-babel-call.el in the 'evaluation' branch. And I've made a start
-   at sketching a parsing algorithm below.
-
-*** discussion
-I believe that this issue should be addressed as a bug rather than as
-a point for new development.   The code in [[file:lisp/org-babel-ref.el][org-babel-ref.el]] already
-resolves variable references in a recursive manner which *should* work
-in the same manner regardless of the depth of the number of nested
-function calls.  This recursive evaluation has the effect of
-implicitly constructing the parse tree that your are thinking of
-constructing explicitly.
-
-Through using some of the commented out debugging statements in
-[[file:lisp/org-babel-ref.el][org-babel-ref.el]] I have looked at what may be going wrong in the
-current evaluation setup, and it seems that nested variables are being
-set using the =:var= header argument, and these variables are being
-overridden by the *default* variables which are being entered through
-the new functional syntax (see the demonstration header below).
-
-I believe that once this bug is fixed we should be back to fully
-resolution of nested arguments.  We should capture this functionality
-in a test to ensure that we continue to test it as we move forward.  I
-can take a look at implementing this once I get a chance.
-
-**** demonstration
-After uncommenting the debugging statements located [[file:lisp/org-babel-ref.el::message%20format%20first%20second%20S%20S%20new%20refere%20new%20referent%20debugging][here]] and more
-importantly [[file:lisp/org-babel-ref.el::message%20nested%20args%20S%20args%20debugging][here]], we can see that the current reference code does
-evaluate the references correctly, and it uses the =:var= header
-argument to set =a=8=, however the default variables specified using
-the functional syntax in =adder(a=3, b=2)= is overriding this
-specification.
-
-***** doesn't work with functional syntax
-
-#+srcname: adder-func(a=3, b=2)
-#+begin_src python 
-a + b
-#+end_src
-
-#+resname: adder-func
-: 5
-
-#+srcname: after-adder-func(arg=adder-func(a=8))
-#+begin_src python 
-arg
-#+end_src
-
-#+resname: after-adder-func
-: 5
-
-***** still does work with =:var= syntax
-
-so it looks like regardless of the syntax used we're not overriding
-the default argument values.
-
-#+srcname: adder-header
-#+begin_src python :var a=3 :var b=2
-a + b
-#+end_src
-
-#+resname: adder-header
-: 5
-
-#+srcname: after-adder-header
-#+begin_src python :var arg=adder-header(a=8, b=0)
-arg
-#+end_src
-
-#+resname: after-adder-header
-: 5
-
-
-*** Parse tree algorithm
-    Seeing as we're just trying to parse a string like
-    f(a=1,b=g(c=2,d=3)) it shouldn't be too hard. But of course there
-    are 'proper' parsers written in elisp out there,
-    e.g. [[http://cedet.sourceforge.net/semantic.shtml][Semantic]]. Perhaps we can find what we need -- our syntax is
-    pretty much the same as python and R isn't it?
-
-    Or, a complete hack, but maybe it would be we easy to transform it
-    to XML and then parse that with some existing tool?
-    
-    But if we're doing it ourselves, something very vaguely like this?
-    (I'm sure there're lots of problems with this)
-
-#+srcname: org-babel-call-parse(call)
-#+begin_src python 
-  ## we are currently reading a reference name: the name of the root function
-  whereami = "refname"
-  node = root = Node()
-  for c in call_string:
-      if c == '(':
-          varnum = 0
-          whereami = "varname" # now we're reading a variable name
-      if c == '=':
-          new = Node()
-          node.daughters = [node.daughters, new]
-          new.parent = node
-          node = new
-          whereami = "refname"
-      if c == ',':
-          whereami = "varname"
-          varnum += 1
-      elif c == ')':
-          node = node.parent
-      elif c == ' ':
-          pass
-      else:
-          if whereami = "varname":
-              node.varnames[varnum] += c
-          elif whereami = "refname":
-              node.name += c
-#+end_src
-    
-*** Example that fails
-    
-#+srcname: adder(a=0, b=0)
-#+begin_src python 
-a+b
-#+end_src
-
-#+srcname: one()
-#+begin_src python :results silent
-1
-#+end_src
-
-This works
-#+srcname: level-one-nesting
-#+begin_src python :var arg=adder(a=one(),b=one())
-arg
-#+end_src
-
-But this doesn't
-#+srcname: level-one-nesting
-#+begin_src python :var arg=adder(a=adder(a=one(),b=one()),b=adder(a=one(),b=one()))
-arg
-#+end_src
-
 ** PROPOSED Default args
 ** PROPOSED Default args
    This would be good thing to address soon. I'm imagining that
    This would be good thing to address soon. I'm imagining that
    e.g. here, the 'caller' block would return the answer 30. I believe
    e.g. here, the 'caller' block would return the answer 30. I believe
@@ -2449,6 +2281,259 @@ plot data using 1:2 with lines
 
 
 
 
 * Bugs [24/36]
 * Bugs [24/36]
+** TODO Fix nested evaluation
+   The current parser / evaluator fails with greater levels of nested
+   function block calls (example below).
+
+*** Initial statement [ded]
+    If we want to overcome this I think we'd have to redesign some of
+    the evaluation mechanism. Seeing as we are also facing issues like
+    dealing with default argument values, and seeing as we now know
+    how we want the library of babel to behave in addition to the
+    source blocks, now might be a good time to think about this. It
+    would be nice to do the full thing at some point, but otoh we may
+    not consider it a massive priority.
+    
+    AIui, there are two stages: (i) construct a parse tree, and (ii)
+    evaluate it and return the value at the root. In the parse tree
+    each node represents an unevaluated value (either a literal value
+    or a reference). Node v may have descendent nodes, which represent
+    values upon which node v's evaluation depends. Once that tree is
+    constructed, then we evaluate the nodes from the tips towards the
+    root (a post-order traversal).
+
+    [This would also provide a solution for concatenating the STDOUTs
+    of called blocks, which is a [[*allow%20output%20mode%20to%20return%20stdout%20as%20value][task below]]; we concatenate them in
+    whatever order the traversal is done in.]
+
+    In addition to the variable references (i.e. daughter nodes), each
+    node would contain the information needed to evaluate that node
+    (e.g. lang body). Then we would pass a function postorder over the
+    tree which would call o-b-execute-src-block at each node, finally
+    returning the value at the root.
+
+    Fwiw I made a very tentative small start at stubbing this out in
+    org-babel-call.el in the 'evaluation' branch. And I've made a start
+    at sketching a parsing algorithm below.
+**** Parse tree algorithm
+    Seeing as we're just trying to parse a string like
+    f(a=1,b=g(c=2,d=3)) it shouldn't be too hard. But of course there
+    are 'proper' parsers written in elisp out there,
+    e.g. [[http://cedet.sourceforge.net/semantic.shtml][Semantic]]. Perhaps we can find what we need -- our syntax is
+    pretty much the same as python and R isn't it?
+
+    Or, a complete hack, but maybe it would be we easy to transform it
+    to XML and then parse that with some existing tool?
+    
+    But if we're doing it ourselves, something very vaguely like this?
+    (I'm sure there're lots of problems with this)
+
+#+srcname: org-babel-call-parse(call)
+#+begin_src python 
+  ## we are currently reading a reference name: the name of the root function
+  whereami = "refname"
+  node = root = Node()
+  for c in call_string:
+      if c == '(':
+          varnum = 0
+          whereami = "varname" # now we're reading a variable name
+      if c == '=':
+          new = Node()
+          node.daughters = [node.daughters, new]
+          new.parent = node
+          node = new
+          whereami = "refname"
+      if c == ',':
+          whereami = "varname"
+          varnum += 1
+      elif c == ')':
+          node = node.parent
+      elif c == ' ':
+          pass
+      else:
+          if whereami = "varname":
+              node.varnames[varnum] += c
+          elif whereami = "refname":
+              node.name += c
+#+end_src
+    
+*** discussion
+I believe that this issue should be addressed as a bug rather than as
+a point for new development.   The code in [[file:lisp/org-babel-ref.el][org-babel-ref.el]] already
+resolves variable references in a recursive manner which *should* work
+in the same manner regardless of the depth of the number of nested
+function calls.  This recursive evaluation has the effect of
+implicitly constructing the parse tree that your are thinking of
+constructing explicitly.
+
+Through using some of the commented out debugging statements in
+[[file:lisp/org-babel-ref.el][org-babel-ref.el]] I have looked at what may be going wrong in the
+current evaluation setup, and it seems that nested variables are being
+set using the =:var= header argument, and these variables are being
+overridden by the *default* variables which are being entered through
+the new functional syntax (see the demonstration header below).
+
+I believe that once this bug is fixed we should be back to fully
+resolution of nested arguments.  We should capture this functionality
+in a test to ensure that we continue to test it as we move forward.  I
+can take a look at implementing this once I get a chance.
+
+**** demonstration
+After uncommenting the debugging statements located [[file:lisp/org-babel-ref.el::message%20format%20first%20second%20S%20S%20new%20refere%20new%20referent%20debugging][here]] and more
+importantly [[file:lisp/org-babel-ref.el::message%20nested%20args%20S%20args%20debugging][here]], we can see that the current reference code does
+evaluate the references correctly, and it uses the =:var= header
+argument to set =a=8=, however the default variables specified using
+the functional syntax in =adder(a=3, b=2)= is overriding this
+specification.
+
+***** doesn't work with functional syntax
+
+#+srcname: adder-func(a=3, b=2)
+#+begin_src python 
+a + b
+#+end_src
+
+#+resname: adder-func
+: 5
+
+#+srcname: after-adder-func(arg=adder-func(a=8))
+#+begin_src python 
+arg
+#+end_src
+
+#+resname: after-adder-func
+: 5
+
+***** still does work with =:var= syntax
+
+so it looks like regardless of the syntax used we're not overriding
+the default argument values.
+
+#+srcname: adder-header
+#+begin_src python :var a=3 :var b=2
+a + b
+#+end_src
+
+#+resname: adder-header
+: 5
+
+#+srcname: after-adder-header
+#+begin_src python :var arg=adder-header(a=8, b=0)
+arg
+#+end_src
+
+#+resname: after-adder-header
+: 5
+
+*** Set of test cases
+**** Both defaults provided in definition
+#+srcname: adder1(a=10,b=20)
+#+begin_src python
+a+b
+#+end_src
+
+#+resname: adder1
+: 30
+
+****** DONE Rely on defaults
+#+lob: adder1( )
+
+#+resname: adder1( )
+: 30
+
+## should be 30
+## OK, but
+******* TODO empty parens () not recognised as lob call
+	E.g. remove spaces between parens above
+
+****** TODO One supplied, one default
+#+lob: adder1(a=0)
+
+#+resname: adder1(a=0)
+: 30
+## should be 10
+
+#+lob: adder1(b=0)
+
+#+resname: adder1(b=0)
+: 30
+## should be 10
+
+****** TODO Both supplied
+#+lob: adder1(a=1,b=2)
+
+#+resname: adder1(a=1,b=2)
+: 30
+
+## should be 3
+
+**** One arg lacks default in definition
+#+srcname: adder2(a=10,b)
+#+begin_src python
+a+b
+#+end_src
+****** TODO Rely on defaults (one of which is missing)
+#+lob: adder2( )
+
+[no output]
+
+## should be error: b has no default
+
+****** TODO Default over-ridden
+#+lob: adder2(a=1)
+
+[no output ]
+## should be error: b has no default
+
+****** DONE Missing default supplied
+#+lob: adder2(b=1)
+
+#+resname: adder2(b=1)
+: 11
+
+## should be 11
+## OK
+
+****** DONE One over-ridden, one supplied
+#+lob: adder2(a=1,b=2)
+
+#+resname: adder2(a=1,b=2)
+: 3
+## should be 3
+
+*** Example that fails
+    
+#+srcname: adder(a=0, b=99)
+#+begin_src python 
+a+b
+#+end_src
+
+#+resname: adder
+: 99
+
+
+#+srcname: one()
+#+begin_src python :results silent
+2
+#+end_src
+
+
+#+srcname: level-one-nesting
+#+begin_src python :var arg=adder(a=one(),b=one())
+arg
+#+end_src
+
+#+resname:
+: 99
+
+#+srcname: level-one-nesting
+#+begin_src python :var arg=adder(a=adder(a=one(),b=one()),b=adder(a=one(),b=one()))
+arg
+#+end_src
+
+#+resname:
+: 99
+
 ** TODO allow srcname to omit function call parentheses
 ** TODO allow srcname to omit function call parentheses
    Someone needs to revisit those regexps. Is there an argument for
    Someone needs to revisit those regexps. Is there an argument for
    moving some of the regexps used to match function calls into
    moving some of the regexps used to match function calls into