title: Alternative condition classes and handlers/restarts that can modify the original expression(s)
body: <p>Inspired by this awesome <a href="http://adv-r.had.co.nz/Exceptions-Debugging.html#custom-signal-classes" rel="nofollow">post</a> I felt like playing around with condition handling a bit more.</p>
  
  <p>I think I got it all figured out for <code>warning</code> and <code>error</code> (didn't check <code>message</code> in detail yet), but out of pure interest at this point I wondered</p>
  
  <ol>
  <li><p>How the same paradigm could be used for alternative conditions (i.e. conditions simply inheriting from <code>condition</code>, not <code>message</code>, <code>warning</code> or <code>error</code>)</p></li>
  <li><p>When, if at all, the use of such alternative conditions would make any sense in the first place (and/or when <code>signalCondition()</code> would actually be used)</p></li>
  <li><p>How I can get a custom restart handler to "go back to the environment where the actual expression was evaluated" so it can "dynamically" work with/modify the original expression(s) (in frames further up the calling stack) in order to accomplish full flexibilty for condition handling</p></li>
  </ol>
  
  <hr>
  
  <h2>Example</h2>
  
  <p>Default condition constructor:</p>
  
  <pre><code>condition &lt;- function(subclass, message, call = sys.call(-1), ...) {
    structure(
      class = c(subclass, "condition"),
      list(message = message, call = call),
      ...
    )
  }
  </code></pre>
  
  <p>Custom alternative condition constructor:</p>
  
  <pre><code>custom_condition &lt;- function(subclass, message, call = sys.call(-1), ...) {
    cond &lt;- condition(subclass, message, call = call, ...)
    message(cond)
  }
  </code></pre>
  
  <p>Example function that issues two alternative conditions at some point:</p>
  
  <pre><code>foo &lt;- function() {
      for (ii in 1:3) {
          message(paste0("Run #: ", ii))
          if (ii == 1) {
              custom_condition(subclass="conditionFooExample",
                  message="I'm just an example condition")
          } else if (ii == 3) {
              custom_condition(subclass="conditionFooExample2",
                  message="I'm just another example condition")
          }
          ii
      }
  }
  </code></pre>
  
  <p>Running without any wrappers such as <code>tryCatch()</code>, <code>withCallingHandlers()</code>, <code>withRestarts()</code> or the like:</p>
  
  <pre><code>foo()
  Run #: 1
  I'm just an example condition
  Run #: 2
  Run #: 3
  I'm just another example condition
  </code></pre>
  
  <p>As I see it, not really useful as I would have gotten the same result when simply issuing the messages directly via <code>message()</code> in <code>foo()</code> instead of creating customs conditions via <code>custom_condition()</code>.</p>
  
  <p>This happens when wrapping it with <code>tryCatch()</code>:</p>
  
  <pre><code>tryCatch(
      foo(),
      conditionFooExample=function(cond) {
          cond
      },
      conditionFooExample2=function(cond) {
          cond
      }
  )
  Run #: 1
  &lt;conditionFooExample in foo(): I'm just an example condition&gt;
  </code></pre>
  
  <p>As we see, the first condition leads to kind of a "graceful exit". As I see it, as is right now, not really useful either because it resembles the behavior of <code>warnings</code>.</p>
  
  <p>So I thought if alternative conditions are to be useful at all, then this whole process would probably need to involve custom condition handlers (e.g. for logging purposes: "write something back to a DB and continue") and something similar to  <code>invokeRestart("muffleWarning")</code> (see <code>?condition</code> and look for <code>muffleWarning</code>) in order to "really continue" (as opposed to "gracefully exiting").</p>
  
  <p>So I gues this would then look something like this (<strong>PSEUDO CODE</strong>)?</p>
  
  <pre><code>withRestarts(
      tryCatch(
          foo(),
          conditionFooExample=function(cond) {
              cond      ## possibly 'message(cond)' instead?
              ## Do something meaningful before invoking a restart
              invokeRestart("conditionFooExample")
          },
          conditionFooExample2=function(cond) {
              cond      ## possibly 'message(cond)' instead?
              ## Do something meaningful before invoking a restart
              invokeRestart("conditionFooExample2")
          }
      ),
      conditionFooExample=function() {
          ## (Maybe) do something more before continuing
  
          ## Then continue:
          invokeRestart("muffleCondition")
      },
      conditionFooExample2=function() {
          ## (Maybe) do something more before continuing
  
          ## Then continue:
          invokeRestart("muffleCondition")
      }
  )
  </code></pre>
  
  <p>Of course, there is no such thing as <code>invokeRestart("muffleCondition")</code> and I'm also not sure if this "architecture" would make any sense. </p>
  
  <p><strong>However, this is where question 3 came up: how do these restart handlers actually work, i.e. how do they get from their frame "one frame up" again?</strong></p>
  
  <p>Last not least I asked myself what would happened if I used <code>signalCondition(cond)</code> instead of <code>message(cond)</code> in <code>custom_condition()</code></p>
  
  <pre><code>custom_condition &lt;- function(subclass, message, call = sys.call(-1), ...) {
    cond &lt;- condition(subclass, message, call = call, ...)
    signalCondition(cond)
  }
  
  foo()
  Run #: 1
  Run #: 2
  Run #: 3
  </code></pre>
  
  <p>So, this seems even more "unnecessary" that before as the function simply terminates.</p>
  
  <p>This is how it would look with <code>tryCatch()</code>:</p>
  
  <pre><code>tryCatch(
      foo(),
      conditionFooExample=function(cond) {
          cond
      },
      conditionFooExample2=function(cond) {
          cond
      }
  )
  
  Run #: 1
  &lt;conditionFooExample in foo(): I'm just an example condition&gt;
  </code></pre>
  
  <p>Well, the behavior itself does make sense, but I could have gotten the same result with an <code>error</code> condition.</p>