Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why F# quotation cannot contains struct?

Tags:

f#

I would like to define a struct, which contains some member methods. And I want to use [<ReflectedDefinition>] to mark that struct member method. But the compiler tells me it is wrong.

First, see this piece of code:

type Int4 =
    val mutable x : int
    val mutable y : int
    val mutable z : int
    val mutable w : int

    [<ReflectedDefinition>]
    new (x, y, z, w) = { x = x; y = y; z = z; w = w }

    [<ReflectedDefinition>]
    member this.Add(a:int) =
        this.x <- this.x + a
        this.y <- this.y + a
        this.z <- this.z + a
        this.w <- this.w + a

    override this.ToString() = sprintf "(%d,%d,%d,%d)" this.x this.y this.z this.w

It compiles. But if I make the type a struct, it cannot be compiled:

[<Struct>]
type Int4 =
    val mutable x : int
    val mutable y : int
    val mutable z : int
    val mutable w : int

    [<ReflectedDefinition>]
    new (x, y, z, w) = { x = x; y = y; z = z; w = w }

    [<ReflectedDefinition>]
    member this.Add(a:int) = // <----------- here the 'this' report compile error
        this.x <- this.x + a
        this.y <- this.y + a
        this.z <- this.z + a
        this.w <- this.w + a

    override this.ToString() = sprintf "(%d,%d,%d,%d)" this.x this.y this.z this.w

I get the following error:

error FS0462: Quotations cannot contain this kind of type

which is point to this in this code.

Anyone has any idea on why I cannot create quotation on a struct member function? I guess it might because that struct is value type, so this pointer should be byref.

like image 564
Xiang Zhang Avatar asked Jul 04 '26 19:07

Xiang Zhang


1 Answers

In fact, the observed compiler error in F# 3.0 reads:

error FS1220: ReflectedDefinitionAttribute may not be applied to an instance member on a struct type, because the instance member takes an implicit 'this' byref parameter

The root cause of the observed behavior is the limitation of F# quotations - you cannot use byref types in the quoted code.

Nevertheless, the consequence of this limitation is applicable only to the instance struct members; static struct members can be decorated with [<ReflectedDefinition]> attribute.

like image 114
Gene Belitski Avatar answered Jul 08 '26 04:07

Gene Belitski