Why am I not allowed to use a reference cell as an argument for the byref parameter in the let function?

This does not work:

let increment(i: int byref) = i <- i + 1
let xxx = ref 0
increment(xxx) // this expression was expected to have type
               // byref<int> but here has type int ref

      

But this works:

let incrementParam(a: int byref) = a <- a + 1
let mutable b = 30
incrementParam(&b)

      

and:

type Incrementor =
    static member Increment(i : int byref) =
       i <- i + 1

let fff = ref 10
Incrementor.Increment(fff) 

      

+3


source to share


2 answers


Because the spec says so. See Type Directed Conversions in Member Invocations (focus), especially the following:



Note. These type-oriented conversions are intended primarily for interoperability with existing .NET-based .NET libraries and do not apply to calls to functions defined in modules or bound locally in expressions.

+6


source


To add some information to the link that Daniel pointed out, the problem is that the type is 'T ref

not the same as the type 'T byref

, so the compiler needs to insert some kind of conversion (to accept the address).

I think this is only supported for contributors, because this is the main scenario (calling COM interop methods, etc.) and because implicit conversions usually compile type inference. Type-oriented conversions are an easier case where the compiler already knows the required type ( 'T byref

). I suppose that if it were allowed for functions, the compiler could infer that the type of the argument should be 'T ref

.



If you want the first sample to work, you must explicitly build 'T byref

by taking the address of the field contents

:

let increment(i: int byref) = i <- i + 1
let xxx = ref 0
increment(&xxx.contents)

      

+5


source







All Articles