[graalvm-users] Strange error

Chris Seaton chris.seaton at oracle.com
Mon Jul 16 14:47:44 PDT 2018


Which do you think is correct? It sounds like you think “[3]” would be correct, but R single-element-vectors are automatically unboxed to doubles aren’t they?

But here’s another way to look at it:


module R

  def self.eval(string)
    Polyglot.eval("R", string)
  end
  
  def self.parse_arg(arg)
    if Truffle::Interop.foreign?(arg)
      arg
    elsif arg.is_a?(Integer)
      arg.to_f
    end
  end
  
  def self.parse2list(*args)
    params = Polyglot.eval("R", "list()")
    args.each_with_index do |arg, i|
      params = R.eval("`[[<-`").call(params, i+1, parse_arg(arg))
    end
    params
  end
  
  def self.exec_function(function, *args)
    pl = R.parse2list(*args)
    R.eval("do.call").call(function, pl)
  end
  
  def self.exec_function_nosplat(function, args)
    pl = R.parse2list(*args)
    R.eval("do.call").call(function, pl)
  end

end

func = Polyglot.eval("R", "c")
vect = R.exec_function(func, 1, 2, 3, 4, 5)

func = Polyglot.eval("R", "`[`")
v1 = R.exec_function(func, vect, -2)

v2 = R.exec_function(func, v1, 2)
p v2.to_s #=> "[3]"

v3 = R.exec_function_nosplat(func, [v1, 2])
p v3.to_s #=> "3.0"


I don’t understand what difference the method definition location in your example is making, but I could reproduce without it so I simplified, and found that maybe the splat has something to do with it. Do you have any thoughts or insights from this version?

Chris

> On 16 Jul 2018, at 19:49, Rodrigo Botafogo <rodrigo.a.botafogo at gmail.com> wrote:
> 
> Hello,
> 
> I've being struggling with this issue for a couple of days, trying to get to a reproducible error.  I must be blind to something really obvious, but I can't find it.  I tried to reduce the code as much as possible and here it is:
> 
> module R
> 
>   #----------------------------------------------------------------------------------------
>   #
>   #----------------------------------------------------------------------------------------
> 
>   def self.eval(string)
>     Polyglot.eval("R", string)
>   end
>     
>   #----------------------------------------------------------------------------------------
>   #
>   #----------------------------------------------------------------------------------------
> 
>   def self.parse_arg(arg)
>     # if this is an R object, leave it alone
>     if (Truffle::Interop.foreign?(arg) == true)
>       return arg
>       # convert integer to double, this is how R understands a number.
>     elsif (arg.is_a? Integer)
>       arg.to_f
>     end
>   end
>   
>   #----------------------------------------------------------------------------------------
>   # Parse all arguments into an R list of arguments
>   #----------------------------------------------------------------------------------------
> 
>   def self.parse2list(*args)
>     params = Polyglot.eval("R", "list()")
>     args.each_with_index do |arg, i|
>       params = R.eval("`[[<-`").call(params, i+1, parse_arg(arg))
>     end
>     params
>   end
> 
>   #----------------------------------------------------------------------------------------
>   # @param function [R function (Interop)] R function to execute
>   # @args [Argument list] arguments for the function
>   #----------------------------------------------------------------------------------------
> 
>   def self.exec_function(function, *args)
>     pl = R.parse2list(*args)
>     # calls the function in R with the parameter list
>     R.eval("do.call").call(function, pl)
>   end
> 
> end
> 
> #========
> # First example: the return value is an array
> #=======
> func = Polyglot.eval("R", "c")
> vect = R.exec_function(func, 1, 2, 3, 4, 5)
> 
> func = Polyglot.eval("R", "`[`")
> v1 = R.exec_function(func, vect, -2)
> 
> v2 = R.exec_function(func, v1, 2)
> p v2.to_s
> #=========
> The printed value here is:
> >> [3]
> 
> #========
> # Second example: the return value is a scalar.  The only difference
> # between the first example and this one is that function ex_f
> # is defined on the global scope.  This function is an exact copy
> # of function exec_function defined in the R module
> #========
> def ex_f(function, *args)
>   pl = R.parse2list(*args)
>   R.eval("do.call").call(function, pl)
> end
> 
> func = Polyglot.eval("R", "c")
> vect = R.exec_function(func, 1, 2, 3, 4, 5)
> 
> func = Polyglot.eval("R", "`[`")
> v1 = R.exec_function(func, vect, -2)
> 
> v2 = ex_f(func, v1, 2)
> p v2.to_s
> #========
> The printed result here is:
> >> 3.0
> 
> 
> Note that the only difference between example 1 and 2 is the definition of function ex_f, copy of execute_function, in the global scope.  I can't understand the printed values and the change from Array to double.
> 
> I have executed this as:
> 
> ruby --polyglot --jvm -Xsingle_threaded strange.rb
> 
> -- 
> Rodrigo Botafogo
> 
> _______________________________________________
> GraalVM-Users mailing list
> GraalVM-Users at oss.oracle.com
> https://oss.oracle.com/mailman/listinfo/graalvm-users




More information about the GraalVM-Users mailing list