emacs-orgmode
[Top][All Lists]
Advanced

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

Re: [O] Difference :header-args: and :header-args+:?


From: Aaron Ecay
Subject: Re: [O] Difference :header-args: and :header-args+:?
Date: Mon, 08 Sep 2014 18:05:26 -0400
User-agent: Notmuch/0.18.1+51~gbbbdf04 (http://notmuchmail.org) Emacs/24.4.50.2 (x86_64-unknown-linux-gnu)

Hi Achim,

2014ko irailak 8an, Achim Gratz-ek idatzi zuen:
> 
> Aaron Ecay writes:
>> Eric Schulte has said <http://mid.gmane.org/address@hidden>
>> that the deprecation of this feature is “premature”.  I didn’t realize
>> at the time that the deprecation was also included in the manual rather
>> than just a code comment.  Possibly it should be un-deprecated.
> 
> It shouldn't, owing to a number of essentially un-fixable corner cases
> and its inherent non-scaleability.

Can you say more about the corner cases?  I looked for discussion on the
mailing list around the time your changes were introduced.  I only found
a message <http://article.gmane.org/gmane.emacs.orgmode/73832> (in a
thread about how/where #+call lines insert their results) that treats
the change as a fait accompli, (“I agree that this didn't make all that
much sense in the past, but with property evaluation and elisp argument
evaluation now anchored to the point of call [...]”)

I could have missed something, of course.

As to the non-scalability, that should be fixed by some combination of
the parser cache and retrieving all properties at once (via
‘org-entry-properties’) rather than ‘org-entry-get’-ing them one-by-one.
There are a couple recent threads about this.  Here’s one
<http://mid.gmane.org/address@hidden> about a reimplementation
of the property API functions in terms of the parser.  Here
<http://mid.gmane.org/address@hidden>
the speed tradeoffs of the two approaches are discussed.  (IOW, as
presently implemented the classical method is not scalable, but said
unscalability is by no means “inherent”.)

> 
>> Certainly I agree that the suggested replacement is less capable.
> 
> Do you have an example of something that it cannot do (modulo the bugs
> and corners of the deprecated syntax)?

See the attached file for two examples, one related to #+call lines and
one not.

Again, can you say more about what you mean by the bugs and corners of
the deprecated syntax?  The #+call behavior doesn’t seem like a bug, but
basically a difference in whether header args are dynamically (wrt point
of call) or lexically (wrt point of definition) scoped.  Dynamic
vs. lexical scoping is not a bug, but a matter of taste/language
design/etc.  Most computer languages with which I’m familiar (Python, R,
C, Scheme/Lisp, ...) use lexical scoping by default, and elisp has been
slowly but steadily moving in that direction for years.  Thus this new
suggested dynamic-type behavior for header args is surprising to me.

The first demonstration in the attachment (not related to #+calls)
seems like a much clearer case of deficiency of the new system: an
inability to inherit different args from different levels.  (Please
factor away from the nonsense strings in place of “yes” and “no” – I
wanted to make it clear where each value was coming from, and assure
that they were not being generated by default.  Of course in a real use
case the values for these header args would be “yes” and “no”.  Also,
one could also demonstrate the problem with header args that can take
an arbitrary string value by design, like :session.)

>From your other mail:

2014ko irailak 8an, Achim Gratz-ek idatzi zuen:
> 
> Rainer M Krug writes:
>> Aaron Ecay <address@hidden> writes:

[...]

>>> Are you aware that you can set individual header args as properties?
>>> Something like (at the file level):
> 
> Are you aware that this doesn't quite do what you think it does, some of
> the time, when things become more complex than your example?

Again, can you say more about what you mean here?  As a personal
anecdote, I have never been surprised by the behavior of “classic”
header arg properties.

> 
>> I was using this deprecated behavior and I was *very* happy with it, but
>> I am trying to adjust to the new syntax.
>> 
>> So how can I use the new syntax?
> 
> If you maybe had an example of what you're trying to do instead of
> asking stuff about things you don't want to do?  Otherwise, have a look
> at
> 
> <orgmode.git>/testing/examples/ob-header-arg-defaults.org

I find the content of this file incredibly dense, and the suggestion
of its use as documentation bordering on a joke.  (Documentation may
not exist, and that just means an area for improvement has been found.
But it’s not as though we’re all going to read that file and suddenly
understand what you mean.)  It looks like it is trying to demonstrate
inheritance and overriding of :var header args.  I can’t figure out
why the #+call in “Overwrite” gets go1, but the addition of “var+ to1”
in “Accumulate” causes this to shift, not to “to1”, but to “ge1”.
That is a very confusing interaction (to name just one).  It’s also not
clear to me how it relates to other header args, since vars supplement
each other, whereas other types of header replace.

-- 
Aaron Ecay
* Prelim

Run this code first:

#+begin_src emacs-lisp
  (require 'cl-lib)
  (defun awe-show-headers (&rest headers)
    (pp-to-string (save-excursion
                    (goto-char org-babel-current-src-block-location)
                    (cl-delete-if-not
                     (lambda (pair) (memq (car pair) headers))
                     (nth 2 (org-babel-get-src-block-info 'light))))))
#+end_src

#+RESULTS:
: awe-show-headers

* Case 1
** The old way
  :PROPERTIES:
  :cache:    foo
  :comments: bar
  :END:

#+begin_src emacs-lisp
(awe-show-headers :cache :comments)
#+end_src

#+RESULTS:
: ((:comments . "bar yes")
:  (:cache . "foo no"))

*** Subtree
    :PROPERTIES:
    :cache:    quux
    :END:

*Good*: we can inherit different header args from multiple levels in the 
hierarchy.

#+begin_src emacs-lisp
(awe-show-headers :cache :comments)
#+end_src

#+RESULTS:
: ((:comments . "bar yes")
:  (:cache . "quux no"))

** The new way
   :PROPERTIES:
   :header-args: :cache foo :comments bar
   :END:

#+begin_src emacs-lisp
(awe-show-headers :cache :comments)
#+end_src

#+RESULTS:
: ((:comments . "bar yes")
:  (:cache . "foo no"))

*** Subtree
    :PROPERTIES:
    :header-args: :cache quux
    :END:

*PROBLEM*: we don’t get =:comments foo= from parent headline (“The new way”)

#+begin_src emacs-lisp
(awe-show-headers :cache :comments)
#+end_src

#+RESULTS:
: ((:comments . "yes")
:  (:cache . "quux no"))

*** Subtree 2
    :PROPERTIES:
    :header-args+: :cache quux
    :END:

*PROBLEM*: we still don’t get =:comments foo= from parent headline even by 
using the +

#+begin_src emacs-lisp
(awe-show-headers :cache :comments)
#+end_src

#+RESULTS:
: ((:comments . "yes")
:  (:cache . "quux no"))

* Case 2

** old way

*** subtree
   :PROPERTIES:
   :var:    awe-x=1
   :END:

#+name: call-me
#+begin_src emacs-lisp
(or (and (boundp 'awe-x) awe-x) "drat")
#+end_src

*** other subtree

*Good*: the variable is bound from the site of definition, not call.

#+call: call-me()

#+RESULTS:
: 1


** new way

*** subtree
   :PROPERTIES:
   :header-args: :var awe-x=1
   :END:

#+name: call-me-new
#+begin_src emacs-lisp
(or (and (boundp 'awe-x) awe-x) "drat")
#+end_src

*** other subtree

*Bad*: the variable doesn’t get bound

#+call: call-me-new()

#+RESULTS:
: drat

reply via email to

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