Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why would you use Builder.Source() in a custom computation expression builder?

Tags:

f#

Reading through the F# 4.0 spec, I saw the following on page 79 of the PDF:

The auxiliary function src(e) denotes b.Source(e) if the innermost ForEach is from the user code instead of generated by the translation, and a builder b contains a Source method. Otherwise, src(e) denotes e.

This is in the context of the spec's detailed (VERY detailed) description of how computation expressions are parsed and turned into a series of method calls on the expression's builder object. Scott Wlaschin's Computation Expressions series, which I found to be invaluable in helping me understand the rest of the concepts behind computation expressions, doesn't mention a Source method, nor does any other reference I've been able to find. (Google isn't much help with this one, as tons of people talk about source code and any references to Source methods gets buried).

I also don't see Source documented anywhere in the MSDN page on computation expressions. The QueryBuilder class uses Source, so I have one example I can look at, but there's no explanation of why this would be useful in other circumstances.

Under what circumstances would you want to have a Source method on a custom computation expression builder? What would be a scenario where the default ForEach handling is inadequate to one's needs and a Source method would be useful?

like image 988
rmunn Avatar asked Feb 09 '16 07:02

rmunn


1 Answers

I do not have any insider knowledge about this, but here is why I think the method exists, based on the translation and the implementation in built-in QueryBuilder.

All the operations in QueryBuilder represent the data source using QuerySource<'R, 'Q> where 'R is the type of elements and 'Q is the kind of data source - either IEnumerable or IQueryable.

The fact that there is just one data type means it does not need to define separate overloads for IQueryable and IEnumerable - which would be otherwise needed because the Run method at the end needs to do different things for IEnumerable and for IQueryable.

So, the Source method lets you transform whatever inputs the query can work on into some "internal representation" of the data source. On the opposite end, the Run method turns the data from this internal representation into ordinary value. (In case of QueryBuilder, you never see the QuerySource type in your own code.)

like image 188
Tomas Petricek Avatar answered Oct 04 '22 22:10

Tomas Petricek