dgkf / dgkf/R

Designing a better backtrace

Open
#65 0 comments 0 reactions 0 assignees View on GitHub
theme-base type-design type-enhancement
Dominant language
Rust
Stars
145
Forks
5
PR merge metrics
No merged PRs in 30d

Description

Soon this project will get to the point where it has some metaprogramming tools, and when it does we'll need a better way to report the backtrace. R's `rlang` is of course tackling this issue as well, so I drew a lot of inspiration from their `trace_back()` output.

After quite a bit of iteration, I think I'm going to aim for something like this (riffing on the output from this [`rlang` example](https://rlang.r-lib.org/reference/trace_back.html)):

```
┬┬──╴1 base::try(identity(f()))
├│──╴2 tryCatch(...)
├│──╴3 tryCatchList(expr, classes, parentenv, handlers)
├│──╴4 tryCatchOne(expr, names, parentenv, handlers[[1L]])
╰│──╴5 doTryCatch(return(expr), name, parentenv, handler)
├──╴6 identity(f())
├──╴7 f()
├──╴8 g()
├──╴9 h()
╰─╴10 base::eval(quote(i()), envir = e)
┄┄┬╴11 i()
╰╴12 j()
```

rlang code for comparison

```r
> e <- new.env(parent = getNamespace("base")) # any env not in call stack
> f <- function() g()
> g <- function() h()
> h <- function() eval(quote(i()), envir = e)
> i <- function() j()
> j <- function() rlang::trace_back()
> try(identity(f()))
# ▆
# 1. ├─base::try(identity(f()))
# 2. │ └─base::tryCatch(...)
# 3. │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
# 4. │ └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
# 5. │ └─base (local) doTryCatch(return(expr), name, parentenv, handler)
# 6. ├─base::identity(f())
# 7. └─global f()
# 8. └─global g()
# 9. └─global h()
# 10. └─base::eval(quote(i()), envir = e)
# 11. └─base::eval(quote(i()), envir = e)
# 12. └─global i()
# 13. └─global j()
```

The evaluation environment can be found by walking up the call stack to the first `─` horizontal bar.

### Design goals

* Less indentation than `rlang`, hopefully improving the experience of scanning vertically through calls
* An easier to follow network diagram in the margin
* While retaining the ability to easily identify the evaluation environment
* Explicitly indicating when environments can not be found in the call stack (as in frame 11)
* Not shown, but in conjunction with #57, showing data environments when we get there

If there are benefits to the `rlang` indentation style, they aren't obvious to me. I think I capture all the same information, but I'd be happy to receive critical feedback enlightening me about what other helpful info might be missing.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.