Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do F# Type Providers check types at compile time

So i'm am learning F#, and looked at this:

F# type providers, how do they work

and this:

http://msdn.microsoft.com/en-us/library/hh361033(v=vs.110).aspx

I'm not very fluent in F#, but my (probably incomplete) understanding is that Type Providers are meant to give you some sort of static type-safe access to external data sources.

However, how do they do this? Since the data source is external, there seems (to me) no way of checking the schema of the data source short of querying it, and querying stuff during compile time (and for code completion!) seems like a bad idea.

If they don't do that, though, there has to be some casting going on to cast the unknown data source into some schema (which can then be type-checked) which has the possibility of failure if the data source can't be casted.

like image 944
Li Haoyi Avatar asked Oct 25 '11 23:10

Li Haoyi


1 Answers

You ask a few good questions:

  1. Does the type provider contact the external data source during compilation?

    Yes. The basic idea of the providers in the FSharp.Data.TypeProviders namespace is that they each wrap a code generator. So to do the same thing in C# or most other languages, you'd have an explicit code generation step (contacting the data source at/before "compile time"). In F#, the process is a little bit more seamless but very similar in principle. The data sources that are accessed by the type providers expose relatively efficient ways of querying the schema, and the type providers contain logic to minimize the number of round trips during compilation.

  2. What happens if the schema changes, or the database is off-line, or...?

    Generally speaking, this is up to the type provider, but the built-in type providers expose a few options to users. In particular, it's possible to indicate that the provider should cache a local copy of the schema in case the database becomes inaccessible (alternatively, it's also possible to force the provider to go against live data, so that errors are reported during compilation right away if any mismatch occurs).

    Again, this isn't too different from a code generation approach in other languages - if the schema changes out from under you, you can either fail fast (if you regenerate the code and your references to the generated code no longer line up as expected), or you can try to muddle through (e.g. by never regenerating the code and hoping that things line up at runtime).

These answers apply to the built-in providers, but as a provider-writer someone could certainly choose to do something different (although I think that the approach that I've outlined makes sense for the majority of external data sources).

like image 66
kvb Avatar answered Sep 28 '22 11:09

kvb