Create reference to an object - r

Question Does R contains the concept of reference to an object.
In python, an equal operator is, in fact, a copy by reference.
For example:
>> a = [1,2,3]
>> b = a
>> b[1] = 10
>> a
[1, 10, 3]
or in C++
vector a(3);
a[1] = 1;
vector& b = a;
b[1] = 10;
// now a[1] = 10

You should probably look at reference classes, but you can also just use plain old environments:
> a=new.env()
> a$data=c(1,2,3)
> b=a
> b$data
[1] 1 2 3
> a$data[1]=99
> b$data
[1] 99 2 3
a and b are the same environment:
> a
<environment: 0xa1799fc>
> b
<environment: 0xa1799fc>
so their contents are the same objects.
I think some of the other R OO systems (R.oo, proto?) use environments like this to implement OO objects and methods.
So, although you can just do this, action-at-a-distance effects like this can cause very hard to find bugs, and you probably shouldn't.

Yes, this feature is present in R, though I've never used it myself. Reference classes (or R5 classes as they are sometimes dubbed) have this kind of behaviour. Fairly detailed documentation are in the link below, along with an example
http://www.inside-r.org/r-doc/methods/ReferenceClasses
There are other questions on SE which link to various presentations which probably contain more examples
What is the significance of the new Reference Classes?

Related

How to interpolate multiple variables in a Markdown string in Julia

In the following Julia 1.5 code:
a, b = 4, 5
"a=$(a), b=($b)" # "a=4, b=5"
using Markdown
md"a=$(a), b=($b)" # a=a, b=b
# but...
Markdown.parse("a=$(a), b=($b)") # "a=4, b=5"
It seems that the Markdown macro thinks two $ indicate a math expression. But the parse handles it OK.
Can someone explain this? is there a way to use the md"..." form for this.
It's not obvious in my opinion, but I think $ with a non-space before is interpreted as a closing LaTeX $ if there is one before.
Some suggestions:
If you're OK with spaces around your = sign, then this works:
julia> md"a = $a, b = $b"
a = 4, b = 5
Or you could make it a list:
julia> md"""
- a=$a
- b=$b
"""
• a=4
• b=5

Refer to struct fields without dot notation (in Julia)

In Julia I've defined a type and I need to write some functions that work with the fields of that type. Some of the functions contain complicated formulas and it gets messy to use the field access dot notation all over the place. So I end up putting the field values into local variables to improve readability. It works fine, but is there some clever way to avoid having to type out all the a=foo.a lines or to have Julia parse a as foo.a etc?
struct Foo
a::Real
b::Real
c::Real
end
# this gets hard to read
function bar(foo::Foo)
foo.a + foo.b + foo.c + foo.a*foo.b - foo.b*foo.c
end
# this is better
function bar(foo::Foo)
a = foo.a
b = foo.b
c = foo.c
a + b + c + a*b - b*c
end
# this would be great
function bar(foo::Foo)
something clever
a + b + c + a*b - b*c
end
Because Julia generally encourages the use of generalized interfaces to interact with fields rather than accessing the fields directly, a fairly natural way of accomplishing this would be unpacking via iteration. In Julia, objects can be "unpacked" into multiple variables by iteration:
julia> x, y = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> x
1
julia> y
2
We can implement such an iteration protocol for a custom object, like Foo. In v0.7, this would look like:
Base.iterate(foo::Foo, state = 1) = state > 3 ? nothing : (getfield(foo, state), state + 1)
Note that 3 is hardcoded (based on the number of fields in Foo) and could be replaced with fieldcount(Foo). Now, you can simply "unpack" an instance of Foo as follows:
julia> a, b, c = Foo("one", 2.0, 3)
Foo("one", 2.0, 3)
julia> a
"one"
julia> b
2.0
julia> c
3
This could be the "something clever" at the beginning of your function. Additionally, as of v0.7, you can unpack the fields in the function argument itself:
function bar((a, b, c)::Foo)
a + b + c + a*b - b*c
end
Although this does require that you mention the field names again, it comes with two potential advantages:
In the case that your struct is refactored and the fields are renamed, all code accessing the fields will remain intact (as long as the field order doesn't change or the iterate implementation is changed to reflect the new object internals).
Longer field names can be abbreviated. (i.e. rather than using the full apples field name, you can opt to use a.)
If it's important that the field names not be repeated, you could define a macro to generate the required variables (a = foo.a; b = foo.b; c = foo.c); however, this would likely be more confusing for the readers of your code and lack the advantages listed above.
As of Julia 1.6, the macros in this package look relevant: https://github.com/mauro3/UnPack.jl.
The syntax would look like:
function bar(foo::Foo)
# something clever!
#unpack a, b, c = f
a + b + c + a*b - b*c
end
In Julia 1.7, it looks like this feature will be added with the syntax
function bar(foo::Foo)
# something clever!
(; a, b, c) = f
a + b + c + a*b - b*c
end
Here is the merged pull request: https://github.com/JuliaLang/julia/pull/39285

Can I use <- instead of = in Julia?

Like in R:
a <- 2
or even better
a ← 2
which should translate to
a = 2
and if possible respect method overloading.
= is overloaded (not in the multiple dispatch sense) a lot in Julia.
It binds a new variable. As in a = 3. You won't be able to use ← instead of = in this context, because you can't overload binding in Julia.
It gets lowered to setindex!. As in, a[i] = b gets lowered to setindex!(a, b, i). Unfortunately, setindex! takes 3 variables while ← can only take 2 variables. So you can't overload = with 3 variables.
But, you can use only 2 variables and overload a[:] = b, for example. So, you can define ←(a,b) = (a[:] = b) or ←(a,b) = setindex!(a,b,:).
a .= b gets lowered to (Base.broadcast!)(Base.identity, a, b). You can overload this by defining ←(a,b) = (a .= b) or ←(a,b) = (Base.broadcast!)(Base.identity, a, b).
So, there are two potentially nice ways of using ←. Good luck ;)
Btw, if you really want to use ← to do binding (like in 1.), the only way to do it is using macros. But then, you will have to write a macro in front of every single assignment, which doesn't look very good.
Also, if you want to explore how operators get lowered in Julia, do f(a,b) = (a .= b), for example, and then #code_lowered f(x,y).
No. = is not an operator in Julia, and cannot be assigned to another symbol.
Disclaimer: You are fully responsible if you will try my (still beginner's) experiments bellow! :P
MacroHelper is module ( big thanks to #Alexander_Morley and #DanGetz for help ) I plan to play with in future and we could probably try it here :
julia> module MacroHelper
# modified from the julia source ./test/parse.jl
function parseall(str)
pos = start(str)
exs = []
while !done(str, pos)
ex, pos = parse(str, pos) # returns next starting point as well as expr
ex.head == :toplevel ? append!(exs, ex.args) : push!(exs, ex)
end
if length(exs) == 0
throw(ParseError("end of input"))
elseif length(exs) == 1
return exs[1]
else
return Expr(:block, exs...) # convert the array of expressions
# back to a single expression
end
end
end;
With module above you could define simple test "language":
julia> module TstLang
export #tst_cmd
import MacroHelper
macro tst_cmd(a)
b = replace("$a", "←", "=") # just simply replacing ←
# in real life you would probably like
# to escape comments, strings etc
return MacroHelper.parseall(b)
end
end;
And by using it you could probably get what you want:
julia> using TstLang
julia> tst```
a ← 3
println(a)
a +← a + 3 # maybe not wanted? :P
```
3
9
What about performance?
julia> function test1()
a = 3
a += a + 3
end;
julia> function test2()
tst```
a ← 3
a +← a + 3
```
end;
julia> test1(); #time test1();
0.000002 seconds (4 allocations: 160 bytes)
julia> test2(); #time test2();
0.000002 seconds (4 allocations: 160 bytes)
If you like to see syntax highlight (for example in atom editor) then you need to use it differently:
function test3()
#tst_cmd begin
a ← 3
a ← a + a + 3 # parser don't allow you to use "+←" here!
end
end;
We could hope that future Julia IDEs could syntax highlight cmd macros too. :)
What could be problem with "solution" above? I am not so experienced julian so many things. :P (in this moment something about "macro hygiene" and "global scope" comes to mind...)
But what you want is IMHO good for some domain specific languages and not to redefine basic of language! It is because readability very counts and if everybody will redefine everything then it will end in Tower of Babel...

Guidance on missing() in R

Suppose a function, G, takes two arguments; a and b: G(a = some number, b = some number).
Now two situations (wondering what commands to use in each case?):
1- if a user puts G(b = some number), will the if(missing(a)){do this} recognize the complete absence of a argument? AND more importantly:
2- if a user puts G(a =, b = some number), still will the if(missing(a)){do this} recognize a = but lack of some number in front of it?
Defining the function as below doesn't throw an error in both the cases:
ch <- function(a=NA,b=NA){ if(is.na(a)) return(b) else( return(a+b)) }
> ch(b=2)
[1] 2
> ch(a=,b=2)
[1] 2

How do I check if an externalptr is NULL from within R

I'm using SWIG to generate wrapper code to access C code from within the R language. The wrapper code uses the R externalptr type to hold references to C pointers. In some situations, those pointers are NULL on the C side, which show up in R as a nil value when displayed. On the R side, calling is.null() and is.na() on the externalptr both return FALSE. For example:
> val = librdf_query_results_get_binding_value(results, 2)
> val
An object of class "_p_librdf_node_s"
Slot "ref":
<pointer: (nil)>
> class(val#ref)
[1] "externalptr"
> is.null(val#ref)
[1] FALSE
> is.na(val#ref)
[1] FALSE
As can be seen from the code output above, the ref slot contains an externalptr, which is "nil". How do I determine from within R that this pointer in C is NULL?
If you want to see the code in context, it is available in GitHub:
https://github.com/ropensci/redland-bindings/blob/master/R/redland/inst/tests/test.redland_base.R#L40
The C solution above is most elegant, but a compiler might not always be available. A solution that does not require compiled code could be something like:
identical(pointer, new("externalptr"))
However this would not work if the object has custom attributes. If this is the case, you could do:
isnull <- function(pointer){
a <- attributes(pointer)
attributes(pointer) <- NULL
out <- identical(pointer, new("externalptr"))
attributes(pointer) <- a
return(out)
}
Again a bit more involved than the C solution, but will work in a simple script on any platform.
For completeness, here's the solution I used. It required a function on the C side, and one on the R side, as suggested by #DirkEddelbuettel. The C function is:
#include <Rinternals.h>
SEXP isnull(SEXP pointer) {
return ScalarLogical(!R_ExternalPtrAddr(pointer));
}
And the wrapper function in R is:
is.null.externalptr <- function(pointer) {
stopifnot(is(pointer, "externalptr"))
.Call("isnull", pointer)
}
For an example of use from within R:
> p <- new("externalptr")
> p
<pointer: (nil)>
> is.null.externalptr(p)
[1] TRUE

Resources