From emil@bode @ending from d@n@@kn@w@nl  Mon Oct 15 11:57:13 2018
From: emil@bode @ending from d@n@@kn@w@nl (Emil Bode)
Date: Mon, 15 Oct 2018 09:57:13 +0000
Subject: [Rd] 
 sys.call() inside replacement functions incorrectly returns *tmp*
In-Reply-To: <CAB8pepwA52R9ZKOe7_83BMWzwsQcZ8eKG+wg3ihBL5+Qs5YPOQ@mail.gmail.com>
References: <CAB8pepwA52R9ZKOe7_83BMWzwsQcZ8eKG+wg3ihBL5+Qs5YPOQ@mail.gmail.com>
Message-ID: <F139A45B-0BDF-41FC-A809-9A00AC2E79A0@dans.knaw.nl>

Hi,

Agreed that it would be better if sys.call() were to return "x" instead of "*tmp*", as it behaves as a local variable. Although I'm not sure what problem it would solve, the effect here is comparable to what happens when calling a function indirectly (although then you could use sys.call(2), which here doesn't work).
 
But your other suggestion, accepting non-existent x without error, would cause a lot of other problems I think. The way I see it, replacement functions are meant to edit a certain aspect of an object/variable. Which only makes sense if it exists in the first place. With your replacement function there may be a use for setting new values but what should e.g. "levels(x) <- letters" do? Make a new empty factor? Discard any results? Make an as-empty-as-possible variable (probably an empty list) with a levels attribute? I think the current behaviour is fine.
In general, I can't see any scenario where you want to "edit" a variable, but make the end-result independent of the original value (Then you'd simply assign, without a custom function). So any replacement function is going to read the original value of x, so is there any downside to requiring it?

Also, I have to say that your example looks confusing to me. Do you want to assign 0 to x, and ignore all other arguments? Or was it your intention to set all variables to 0? And having an ellipsis argument only makes sense in my experience if these arguments are optional. Which would mean myreplacementfunction() = 0 should be a valid call, but I can't see what that would be expected to do. So I would at least make the call `myreplacementfunction(x, ..., value).
The reason y and z are "right" is because these are simple extra input parameters, which can have any value, including missing, they needn't be evaluated.

Best regards, 
Emil Bode
 
Data-analyst
 
+31 6 43 83 89 33
emil.bode at dans.knaw.nl
 
DANS: Netherlands Institute for Permanent Access to Digital Research Resources
Anna van Saksenlaan 51 | 2593 HW Den Haag | +31 70 349 44 50 | info at dans.knaw.nl <mailto:info at dans.kn> | dans.knaw.nl <applewebdata://71F677F0-6872-45F3-A6C4-4972BF87185B/www.dans.knaw.nl>
DANS is an institute of the Dutch Academy KNAW <http://knaw.nl/nl> and funding organisation NWO <http://www.nwo.nl/>. 

?On 15/10/2018, 02:20, "R-devel on behalf of Abs Spurdle" <r-devel-bounces at r-project.org on behalf of spurdle.a at gmail.com> wrote:

    Kia Ora
    
    Let's say we have:
    "myreplacementfunction<-" = function (..., value)
    {	call = sys.call ()
    	print (as.list (call) )
    	0
    }
    
    Then we call:
    x = 0
    myreplacementfunction (x, y, z) = 0
    
    It will return:
    [[1]]
    `myreplacementfunction<-`
    
    [[2]]
    `*tmp*`
    
    [[3]]
    y
    
    [[4]]
    z
    
    $value
    <promise: 0x06fb6968>
    
    There's two problems here.
    Firstly, x has to be defined otherwise we get an error message.
    Secondly, the first argument is returned as *tmp*.
    
    Both are incorrect.
    
    It should be possible to call the function without defining x.
    And it should return x rather than *tmp*.
    In other words, replacement function calls should be the same as other
    function calls.
    
    Although it gets y and z right.
    
    
    kind regards
    Abs
    
    ______________________________________________
    R-devel at r-project.org mailing list
    https://stat.ethz.ch/mailman/listinfo/r-devel
    



[Rd] sys.call() inside replacement functions incorrectly returns *tmp*
Emil Bode