Closed sebffischer closed 1 month ago
The problem here is that the Context::eval_list_lazy
method which substitute
uses, evaluates certain expressions:
I also realized that R evaluates literals to their vectors even when quoting:
> quote(1)
[1] 1
> quote("a")
[1] "a"
> quote(c("a", "b"))
c("a", "b")
>
I think it would be more consistent if literals were not evaluated by quote()
and (it makes sense that substitute()
substitute(1)
evaluates to c(1)
but for quote()
I think it's inconsistent).
In principle I think this can be solved by not evaluating the arguments in Context::eval_list_lazy()
Consider
The root cause of this is a combination of:
CallStack::eval_list_lazy
: https://github.com/dgkf/R/blob/6c5e30465c6971d0f48f5086fc4a63d622cd519f/src/context/core.rs#L112-L118 I believe this should not be the case and we should still maintain them as expressions.substitute()
expects its arguments to be promises: https://github.com/dgkf/R/blob/6c5e30465c6971d0f48f5086fc4a63d622cd519f/src/callable/primitive/substitute.rs#L58-L60Solving this requires that
CallStack::eval_list_lazy
does not evaluate anything but stores the expressions as promises.There is also a related problem, that promises contained in an
Expr::Ellipsis(_)
are currently not evaluated byCallStack::eval_list_eager
. If one implements the above fix, this means that(fn(...) list(...))(1, 2)
returns a list of promises instead oflist(1, 2)
.In princple there is also the question whether
dgkf/R
should behave like R with respect to literals. InR
, we havequote(1) == 1
evaluating toTRUE
. I tend to think that it is more consistent to distinguish between the expression1
and the evaluated length one vector[1] 1
.More comments: