[Rd] How to assign NULL value to pairlist element while keeping it a pairlist?

Henrik Bengtsson henrik.bengtsson at gmail.com
Wed Oct 19 19:25:25 CEST 2016


On Sat, Oct 15, 2016 at 2:00 AM, Martin Maechler
<maechler at stat.math.ethz.ch> wrote:
>>>>>> Michael Lawrence <lawrence.michael at gene.com>
>>>>>>     on Wed, 12 Oct 2016 15:21:13 -0700 writes:
>
>     > Thanks, this was what I expected. There is a desire to
>     > eliminate the usage of pairlist from user code, which
>     > suggests the alternative of allowing for function
>     > arguments to be stored in lists. That's a much deeper
>     > change though.
>
> and I hope we would not go there just for the purpose of
> eliminating pairlists from user code, would we ?
>
> As nobody else has mentioned it, I'd really  like to mention the
> two (actually 3) functions important for dealing with function
> argument lists much more transparently than the
> as.list(<function>) things below:
>
>   formals(<f>)
>   formals(<f>) <- <arglist>      #  and
>   alist()
>
> for creating / modifying function argument lists (which are
> pairlists, but the user does not need to know really).
> Or did you imply, Henrik, that would you want is not achievable
> with these?

Martin, thanks for bringing these options up.  Just to make sure no
one misreads these comments - I'm not operating on as.list(expr) - it
was just used to show the content of the expression.    In my case,
I'm operating / modifying expressions and not functions per se, e.g.

  expr <- quote(function(x = 1) x)

It's not clear to me how I would go about to modify this to be the
equivalent of:

  expr <- quote(function(x = NULL) x)

without having to:

  f <- eval(expr)
  formals(f) <- list(x=NULL)
  expr <- bquote(.(f))

/Henrik

>
> Martin
>
>     > On Wed, Oct 12, 2016 at 12:31 PM, Henrik Bengtsson
>     > <henrik.bengtsson at gmail.com> wrote:
>     >> Michael, thanks for this info.
>     >>
>     >> I've stumbled upon this in a case where I walk an R expression (the
>     >> AST) and (optionally) modifies it (part of the globals package).  In R
>     >> expressions, a function definition uses a pairlist to represent the
>     >> arguments.  For example,
>     >>
>     >>> expr <- quote(function(x = 1) x)
>     >>> str(as.list(expr))
>     >> List of 4
>     >> $ : symbol function
>     >> $ :Dotted pair list of 1
>     >> ..$ x: num 1
>     >> $ : symbol x
>     >> $ :Class 'srcref'  atomic [1:8] 1 15 1 29 15 29 1 1
>     >> .. ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile'
>     >> <environment: 0x13918b8>
>     >>
>     >> Here the 2nd element is a pairlist:
>     >>
>     >>> str(expr[[2]])
>     >> Dotted pair list of 1
>     >> $ x: num 1
>     >>> typeof(expr[[2]])
>     >> [1] "pairlist"
>     >>
>     >> Now say that I want to update the default value of argument 'x', which
>     >> is currently 1, to NULL.  Then I do:
>     >>
>     >>> expr[[2]][1] <- list(x = NULL)
>     >>
>     >> At this step, I end up with an expression 'expr' where the arguments
>     >> are no longer represented by a pairlist:
>     >>
>     >>> str(expr[[2]])
>     >> List of 1
>     >> $ x: NULL
>     >>> typeof(expr[[2]])
>     >> [1] "list"
>     >>
>     >> More importantly, at this point 'expr' no longer holds a valid R expression:
>     >>
>     >>> expr
>     >> Error: badly formed function expression
>     >>
>     >> The solution is to make sure we have a pairlist:
>     >>
>     >>> expr[[2]] <- as.pairlist(expr[[2]])
>     >>> expr
>     >> function(x = NULL) x
>     >>
>     >>
>     >> I agree it would be nice to fix this for consistency, but if you bump
>     >> into major issues, at least I can live with having to use an explicit
>     >> as.pairlist().
>     >>
>     >> Thanks
>     >>
>     >> Henrik
>     >>
>     >> On Wed, Oct 12, 2016 at 10:53 AM, Michael Lawrence
>     >> <lawrence.michael at gene.com> wrote:
>     >>> Hi Henrik,
>     >>>
>     >>> It would help to understand your use case for pairlists.
>     >>>
>     >>> Thanks,
>     >>> Michael
>     >>>
>     >>> On Wed, Oct 12, 2016 at 9:40 AM, Michael Lawrence <michafla at gene.com> wrote:
>     >>>> The coercion is probably the most viable workaround for now, as it's
>     >>>> consistent with what happens internally for calls. All pairlists/calls
>     >>>> are converted to list for subassignment, but only calls are converted
>     >>>> back. My guess is that the intent was for users to move from using a
>     >>>> pairlist to the "new" (almost 20 years ago) list. In my opinion,
>     >>>> consistency trumps "convenience" in this case. If others agree, I'll
>     >>>> change it to also coerce back to pairlist.
>     >>>>
>     >>>> Michael
>     >>>>
>     >>>> On Wed, Oct 12, 2016 at 9:20 AM, Henrik Bengtsson
>     >>>> <henrik.bengtsson at gmail.com> wrote:
>     >>>>> Hi, I seem to not be able to assign NULL to an element of a pairlist
>     >>>>> without causing it to be coerced to a plain list.  For example:
>     >>>>>
>>>>>> x <- pairlist(1, 2)
>>>>>> class(x)
>     >>>>> [1] "pairlist"
>     >>>>>
>>>>>> x[1] <- list(NULL)
>>>>>> class(x)
>     >>>>> [1] "list"
>     >>>>>
>     >>>>> This actually true for all [()<- assignments regardless of list value, e.g.
>     >>>>>
>>>>>> x <- pairlist(1, 2)
>>>>>> x[1] <- list(0)
>     >>>>> [1] "list"
>     >>>>>
>     >>>>> I also tried assigning a pairlist(), but still the same problem:
>     >>>>>
>>>>>> x <- pairlist(1, 2)
>>>>>> x[1] <- pairlist(0)
>     >>>>> [1] "list"
>     >>>>>
>     >>>>> The only workaround I'm aware of is to:
>     >>>>>
>     >>>>> x <- as.pairlist(x)
>     >>>>>
>     >>>>> at the end.  Any other suggestions?
>     >>>>>
>     >>>>> Thanks,
>     >>>>>
>     >>>>> Henrik
>     >>>>>
>     >>>>> ______________________________________________
>     >>>>> R-devel at r-project.org mailing list
>     >>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>
>     > ______________________________________________
>     > R-devel at r-project.org mailing list
>     > https://stat.ethz.ch/mailman/listinfo/r-devel



More information about the R-devel mailing list