Skip to content

how to get a primitive function object

11 messages · Wacek Kusnierczyk, Patrick Burns, Duncan Murdoch +1 more

#
Yi Zhang wrote:
i was sort-of joking, though it's a real option if you want it. 

but seriously, there's no reason for the &%#* lamenting:

x <- 1
'<-' = function(x,y) 0
x <- 2
# 0

.Primitive('<-')(x,2)
x
# 2

base::'<-'(x, 3)
x
# 3

base::'<-'('<-', base::'<-')
x <- 4
x
# 4

vQ
#
I'm still not sure if this can help solve my problem. If I want to
overwrite the `<-` operator for a particular type of objects, but
preserve its effect for other regular objects (in other words, if I do
x<-5 with my new <-, x will be 5 and nothing strange happens), then
what should I put in the [ ] below?
old <- `<-`
old(`<-`, function(x, value){
  if (value is my type) do something
  [ ] # to bind the object value to symbol x: no matter what you do
here, the binding/assignment is local within this function?!
})

Hope I have made myself clear. Thanks,
#
On 22/01/2009 4:50 PM, Yi Zhang wrote:
You can use parent.frame() as the pos or envir argument to assign(), and 
then the assignment happens in the caller's frame.  And assign() is also 
  another way out if you overwrite <- with something that doesn't work; 
just call it to reassign base::`<-` to it.  Or just rm(`<-`) to unhide 
the original one.

Duncan Murdoch
#
Duncan Murdoch wrote:
unless you have redefined rm as well, that is.

vQ
#
If I understand properly, you want '<-' to be
a generic function, which it currently isn't.
There may be a way to fake that (I can't think
of any).

But I'm wondering if you should rethink what
you want.  The only reason that I can think of
that you would want to change '<-' is because
of some extra side effect that you want to happen.
That is not in the spirit of R.

Patrick Burns
patrick at burns-stat.com
+44 (0)20 8525 0696
http://www.burns-stat.com
(home of "The R Inferno" and "A Guide for the Unwilling S User")
Yi Zhang wrote:
#
Wacek Kusnierczyk wrote:
Right, but then there's remove, or base::rm.  Unless you redefined 
remove and `::`.

So here's the question for a frustrating contest:  is it possible to 
define enough functions in the global environment to render your R 
session completely unrecoverable?  (I think it probably is.)  And what's 
the minimal set, or the minimal script to brick your R?  No manipulating 
the search list or writing anywhere but the global environment is allowed. 

Duncan Murdoch
#
Duncan Murdoch wrote:
you might want to specify what 'completely unrecoverable' means, and
what approaches are allowed.

for the former, i guess that:
- 'incompletely recoverable' means that there is at least one function
name in the global environment such that its value has been redefined
and it's not possible, within the session, to revert the binding to the
original value;
- 'completely unrecoverable' means that if there are any function names
with redefined bindings in the global environment, it is not possible,
within the session, to revert the binding for any of them.

you might also mean the extreme situation where there is no function
name that has not been redefined and it is not possible to recover the
original binding for any function name, but i guess this is not what you
mean.  (if you do, then i think the answer is negative, what should be
fairly easy to prove.)

the two cases are effectively equivalent:
- if we are in a completely unrecoverable situation, then there is at
least one function name that cannot be reverted to the original value,
hence the situation is also incompletely recoverable (for those
logically inclined, there is one obvious completely unrecoverable
situation, one in which no function name has been redefined;  i'll
ignore this void case);
- conversely, if we are in an incompletely recoverable situation with n
function names redefined of which m are recoverable, recovering those m
leads to a completely unrecoverable situation. 

note, 'unrecoverable' does not necessarily mean useless.

for the latter above (allowed approaches), i hope that using 'assign' is
ok.  you have already hinted a solution;  i believe, naively, that it
satisfies the requirement:

for (f in strsplit('remove rm :: .Primitive .Internal', split=' ')[[1]])
    assign(f, function() 'roobisch')

as far as i can see, this renders a completely unrecoverable, but still
pretty useful session.


vQ
#
On Fri, Jan 23, 2009 at 5:15 AM, Patrick Burns <pburns at pburns.seanet.com> wrote:
Yes, I wanted some side effect of '<-', to have my own reference
counting for some large resource. I guess this is already the most
non-intrusive way I can think of--initially I modified R's source
code, an even worse option.

  
    
#
On Fri, Jan 23, 2009 at 9:40 AM, Wacek Kusnierczyk
<Waclaw.Marcin.Kusnierczyk at idi.ntnu.no> wrote:

            
I'm already at a somewhat messy situation, as shown in the following code:
# in .onLoad of a package
env <- as.environment('package:base')
unlockBinding('<-',env)
assign('<-', newAssign, envir=env)
.Internal(lockBinding(as.name('<-'), env)) #not using lockBinding
directly because it calls '<-'

It gave me this error: Error: evaluation nested too deeply: infinite
recursion / options(expressions=)?
I have no clue why infinite recursion...
#
On 1/23/2009 1:47 PM, Yi Zhang wrote:
External pointers are the standard way to do that.  You don't need to 
worry about reference counting, R's garbage collector will call a 
finalizer when it doesn't need the object any more.

I think the usual example of this is the RODBC package, which maintains 
database connections that way.

If it and the Writing R Extensions manual aren't enough docs for you, 
you should probably move the question to the R-devel list:  this is 
pretty technical for R-help.

Duncan Murdoch
#
On Fri, Jan 23, 2009 at 2:50 PM, Duncan Murdoch <murdoch at stats.uwo.ca> wrote:

            
Thanks. I've read all the manuals and my situation is more complicated
than the external ptrs and finalizers can handle. I'll probe the
R-devel list and see what I can get.