Skip to content

Type annotations for R function parameters.

6 messages · Оботуров Артем, Duncan Murdoch, Deepayan Sarkar +1 more

#
On 13-08-30 5:19 AM, ???????? ????? wrote:
It's very common for R functions to accept many different types for the 
same argument on input, and somewhat common for the type of output to 
depend on the inputs, so this looks hard:  that's why those front ends 
need work by hand.

Duncan Murdoch
#
On Fri, Aug 30, 2013 at 2:49 PM, ???????? ????? <oboturov at gmail.com> wrote:
See

http://bioconductor.org/packages/2.12/bioc/html/TypeInfo.html

-Deepayan
#
On 13-08-30 7:22 AM, ???????? ????? wrote:
Yes, that's why I said this is hard.
Converters aren't sufficient.  For example, many functions that take 
input from files accept a filename as a character string or a connection 
object for the input parameter.  The character string is converted to a 
connection using file() (sometimes "" is converted to stdin() or 
stdout()), but often other things are done as well, e.g. code to close 
the connection at the end of the function call.

For example, here is the code that examines the "con" argument to the 
readLines() function:

     if (is.character(con)) {
         con <- file(con, "r")
         on.exit(close(con))
     }

The cat() function is a little more complicated, and the parse() 
function has much more extensive calculations involving its "file" 
argument, because it needs to set debugging information and produce 
diagnostic messages.

Duncan Murdoch
#
The type constraints in lambda.r make this relatively easy. The idea is to add a declaration before a function that provides static typing on the function arguments. The type constraint also specifies the return type, so it would be straightforward to construct a graph. Where a type variable is used, then there would need to be a run-time determination for the actual types as happens in Haskell. Obviously to have a complete graph of a program would require the whole program to be written using lambda.r.

For example you can decorate two separate function clauses each with their own type constraint.

slice(x, pivot, inclusive) %::% a : numeric : logical : list
slice(x, pivot, inclusive=FALSE) %as% {
  left <- x[1:pivot]
  right <- x[(pivot+as.numeric(!inclusive)):length(x)]
  list(left, right)
}

slice(x, expression) %::% a : logical : list
slice(x, expression) %as% {
  left <- x[expression]
  right <- x[!expression]
  list(left, right)
}

This calls the first clause since the second argument is numeric.
[[1]]
[1]  1.2468112 -0.2795106  0.5775026  1.0521653

[[2]]
[1] -1.0493246 -2.0634126  0.0368455 -1.8431248 -0.3630197  0.1015901


This calls the second clause since x < 0 is logical.
[[1]]
[1] -0.2795106 -1.0493246 -2.0634126 -1.8431248 -0.3630197

[[2]]
[1] 1.2468112 0.5775026 1.0521653 0.0368455 0.1015901


This fails since no clause of the function accepts a character as the second argument.
Error in UseFunction(slice, "slice", ...) :
  No valid function for 'slice(c(1.24681120969809,-0.279510617209735,0.577502630574721,1.05216534148533, ...),a)'


Warm Regards,
Brian
On Aug 30, 2013, at 5:19 AM, ???????? ????? <oboturov at gmail.com> wrote: