Hello Andrew,
I try now to understand the evaluation of the expression:
e = expression(r(x) <- 1)
# parameter named "value" seems to be required;
'r<-' = function(x, value) {print("R");}
eval(e, list(x=2))
# [1] "R"
# both versions work
'r<-' = function(value, x) {print("R");}
eval(e, list(x=2))
# [1] "R"
### the Expression
e[[1]][[1]] # "<-", not "r<-"
e[[1]][[2]] # "r(x)"
The evaluation of "e" somehow calls "r<-", but evaluates
also the
argument of r(...). I am still investigating what is actually happening.
Sincerely,
Leonard
On 9/13/2021 9:15 PM, Andrew Simmons wrote:> R's parser doesn't work the way you're expecting it to. When
doing an
> assignment like:
>
>
> padding(right(df)) <- 1
>
>
> it is broken into small stages. The guide "R Language Definition"
> claims that the above would be equivalent to:
>
>
> `<-`(df, `padding<-`(df, value = `right<-`(padding(df), value =
1)))
>
>
> but that is not correct, and you can tell by using `substitute` as you
> were above. There isn't a way to do what you want with the syntax you
> provided, you'll have to do something different. You could add a
> `which` argument to each style function, and maybe put the code for
> `match.arg` in a separate function:
>
>
> match.which <- function (which)
> match.arg(which, c("bottom", "left", "top",
"right"), several.ok = TRUE)
>
>
> padding <- function (x, which)
> {
> ? ? which <- match.which(which)
> ? ? # more code
> }
>
>
> border <- function (x, which)
> {
> ? ? which <- match.which(which)
> ? ? # more code
> }
>
>
> some_other_style <- function (x, which)
> {
> ? ? which <- match.which(which)
> ? ? # more code
> }
>
>
> I hope this helps.
>
> On Mon, Sep 13, 2021 at 12:17 PM Leonard Mada <leo.mada at syonic.eu
> <mailto:leo.mada at syonic.eu>> wrote:
>
> Hello Andrew,
>
>
> this could work. I will think about it.
>
>
> But I was thinking more generically. Suppose we have a series of
> functions:
> padding(), border(), some_other_style();
> Each of these functions has the parameter "right" (or the
group of
> parameters c("right", ...)).
>
>
> Then I could design a function right(FUN) that assigns the value
> to this parameter and evaluates the function FUN().
>
>
> There are a few ways to do this:
>
> 1.) Other parameters as ...
> right(FUN, value, ...) = value; and then pass "..." to FUN.
> right(value, FUN, ...) = value; # or is this the syntax? (TODO:
> explore)
>
> 2.) Another way:
> right(FUN(...other parameters already specified...)) = value;
> I wanted to explore this 2nd option: but avoid evaluating FUN,
> unless the parameter "right" is injected into the call.
>
> 3.) Option 3:
> The option you mentioned.
>
>
> Independent of the method: there are still weird/unexplained
> behaviours when I try the initial code (see the latest mail with
> the improved code).
>
>
> Sincerely,
>
>
> Leonard
>
>
> On 9/13/2021 6:45 PM, Andrew Simmons wrote:
>> I think you're trying to do something like:
>>
>> `padding<-` <- function (x, which, value)
>> {
>> ? ? which <- match.arg(which, c("bottom",
"left", "top",
>> "right"), several.ok = TRUE)
>> ? ? # code to pad to each side here
>> }
>>
>> Then you could use it like
>>
>> df <- data.frame(x=1:5, y = sample(1:5, 5))
>> padding(df, "right") <- 1
>>
>> Does that work as expected for you?
>>
>> On Mon, Sep 13, 2021, 11:28 Leonard Mada via R-help
>> <r-help at r-project.org <mailto:r-help at
r-project.org>> wrote:
>>
>> I try to clarify the code:
>>
>>
>> ###
>> right = function(x, val) {print("Right");};
>> padding = function(x, right, left, top, bottom)
>> {print("Padding");};
>> 'padding<-' = function(x, ...) {print("Padding
= ");};
>> df = data.frame(x=1:5, y = sample(1:5, 5)); # anything
>>
>> ### Does NOT work as expected
>> 'right<-' = function(x, value) {
>> ???? print("This line should be the first printed!")
>> ???? print("But ERROR: x was already evaluated, which
printed
>> \"Padding\"");
>> ???? x = substitute(x); # x was already evaluated before
>> substitute();
>> ???? return("Nothing"); # do not now what the
behaviour
>> should be?
>> }
>>
>> right(padding(df)) = 1;
>>
>> ### Output:
>>
>> [1] "Padding"
>> [1] "This line should be the first printed!"
>> [1] "But ERROR: x was already evaluated, which printed
>> \"Padding\""
>> [1] "Padding = " # How did this happen ???
>>
>>
>> ### Problems:
>>
>> 1.) substitute(x): did not capture the expression;
>> - the first parameter of 'right<-' was already
evaluated,
>> which is not
>> the case with '%f%';
>> Can I avoid evaluating this parameter?
>> How can I avoid to evaluate it and capture the expression:
>> "right(...)"?
>>
>>
>> 2.) Unexpected
>> 'padding<-' was also called!
>> I did not know this. Is it feature or bug?
>> R 4.0.4
>>
>>
>> Sincerely,
>>
>>
>> Leonard
>>
>>
>> On 9/13/2021 4:45 PM, Duncan Murdoch wrote:
>> > On 13/09/2021 9:38 a.m., Leonard Mada wrote:
>> >> Hello,
>> >>
>> >>
>> >> I can include code for "padding<-"as
well, but the error
>> is before that,
>> >> namely in 'right<-':
>> >>
>> >> right = function(x, val) {print("Right");};
>> >> # more options:
>> >> padding = function(x, right, left, top, bottom)
>> {print("Padding");};
>> >> 'padding<-' = function(x, ...)
{print("Padding = ");};
>> >> df = data.frame(x=1:5, y = sample(1:5, 5));
>> >>
>> >>
>> >> ### Does NOT work
>> >> 'right<-' = function(x, val) {
>> >> ? ? ??? print("Already evaluated and also does
not use
>> 'val'");
>> >> ? ? ??? x = substitute(x); # x was evaluated before
>> >> }
>> >>
>> >> right(padding(df)) = 1;
>> >
>> > It "works" (i.e. doesn't generate an error)
for me, when I
>> correct
>> > your typo:? the second argument to `right<-` should be
>> `value`, not
>> > `val`.
>> >
>> > I'm still not clear whether it does what you want with
that
>> fix,
>> > because I don't really understand what you want.
>> >
>> > Duncan Murdoch
>> >
>> >>
>> >>
>> >> I want to capture the assignment event inside
"right<-"
>> and then call
>> >> the function padding() properly.
>> >>
>> >> I haven't thought yet if I should use:
>> >>
>> >> padding(x, right, left, ... other parameters);
>> >>
>> >> or
>> >>
>> >> padding(x, parameter) <- value;
>> >>
>> >>
>> >> It also depends if I can properly capture the
unevaluated
>> expression
>> >> inside "right<-":
>> >>
>> >> 'right<-' = function(x, val) {
>> >>
>> >> # x is automatically evaluated when using
'f<-'!
>> >>
>> >> # but not when implementing as '%f%' =
function(x, y);
>> >>
>> >> }
>> >>
>> >>
>> >> Many thanks,
>> >>
>> >>
>> >> Leonard
>> >>
>> >>
>> >> On 9/13/2021 4:11 PM, Duncan Murdoch wrote:
>> >>> On 12/09/2021 10:33 a.m., Leonard Mada via R-help
wrote:
>> >>>> How can I avoid evaluation?
>> >>>>
>> >>>> right = function(x, val)
{print("Right");};
>> >>>> padding = function(x)
{print("Padding");};
>> >>>> df = data.frame(x=1:5, y = sample(1:5, 5));
>> >>>>
>> >>>> ### OK
>> >>>> '%=%' = function(x, val) {
>> >>>> ?? ??? x = substitute(x);
>> >>>> }
>> >>>> right(padding(df)) %=% 1; # but ugly
>> >>>>
>> >>>> ### Does NOT work
>> >>>> 'right<-' = function(x, val) {
>> >>>> ?? ??? print("Already evaluated and also
does not use
>> 'val'");
>> >>>> ?? ??? x = substitute(x); # is evaluated
before
>> >>>> }
>> >>>>
>> >>>> right(padding(df)) = 1
>> >>>
>> >>> That doesn't make sense.? You don't have a
`padding<-`
>> function, and
>> >>> yet you are trying to call right<- to assign
something to
>> padding(df).
>> >>>
>> >>> I'm not sure about your real intention, but
assignment
>> functions by
>> >>> their nature need to evaluate the thing they are
>> assigning to, since
>> >>> they are designed to modify objects, not create
new ones.
>> >>>
>> >>> To create a new object, just use regular
assignment.
>> >>>
>> >>> Duncan Murdoch
>> >
>>
>> ______________________________________________
>> R-help at r-project.org <mailto:R-help at r-project.org>
mailing
>> list -- To UNSUBSCRIBE and more, see
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> <https://stat.ethz.ch/mailman/listinfo/r-help>
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> <http://www.R-project.org/posting-guide.html>
>> and provide commented, minimal, self-contained, reproducible
>> code.
>>
[[alternative HTML version deleted]]