Skip to content
Johan Verwey edited this page Jun 11, 2013 · 4 revisions

Expression Trees

In F#, a unique language feature called quotations, allows you to retrieve the expression tree for any given piece of F# code. An expression tree is a description of the desired computation, rather than the computation itself. This is very useful for running queries (written in F#) on a remote database, where it will be translated to TSQL. We can use this same mechanism to easily translate our desired computations into something that can be executed on a GPU.

From the statements:

    let pos = Vector4(1.0f,0.0f,0.0f,1.0f)
    let worldMatrix = Matrix.identity
    let expr = <@pos * worldMatrix@>

we get the following expression:

val expr : Quotations.Expr< Vector4 > = Call (None, op_Multiply, [PropertyGet (None, pos, []), PropertyGet (None, worldMatrix, [])])

Note that any code enclosed by the <@ ... @> symbols are regarded as a quotation. From the type information we can see that the above expression is a function call to a method op_Multiply, which takes two parameters, pos and worldMatrix. These two variables are of type PropertyInfo which contains information about the input parameters such as their names and types. To translate this small snippet to HLSL, we just need to map the op_Multiply function call to the mul function call. For a great introduction in using quotations, visit Kurt Schelfthout's blog, Forty Six and Two

Pattern Matching

F# is not the only language that is able to be easily converted to an expression tree. C# Expressions for example offer similiar functionality. However, F#'s powerful pattern matching capibilities makes it much easier for us to evaluate these recursive data structures.

 match(expr) with<br>
| Call(_, opMultiply, param1, param2) -> sprintf "mul(%s,%s)" param1.Name param2.Name<br>
| _ -> failwith "Unsupported expression..."

This example is of course a bit over simplified. In reality, the parameters to the mul operator could themselves be expressions. Fortunately F# pattern matching makes parsing recursive data structures a breeze and one can whip up a basic translator in a few hundred lines of code.

Clone this wiki locally