-
Notifications
You must be signed in to change notification settings - Fork 288
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support portable libraries #5
Conversation
Great to see the cross-targeting being addressed! Here's some guidance based on many months experience doing cross-targeting (feel free to ignore it :) )
Keith and I wrote up some full guidelines, we'll dig them out and post them. |
It would be interesting to see the rest of your guidelines. There's really very little information around on how to do type providers. And if you could release any eventual tools that you might have used to debug the freebase type provider at ms it would be great. To check if it's all working, I have go through all methods and properties to make sure they don't complaining about a missingtype in the runtime dll |
I suppose the JSON + XML + WorldBank type providers are quite simple and use uniform style, so it would probably be possible to fixup the quotation literals and make this work. On the other hand, the code that is generally included in quotation literals is not too complicated and it might be possible to get rid of it without too much pain (the code already cannot use it when using some fancy generics). I'll experiment and see... perhaps we could get something like this to work:
becomes:
Of course, this is just an extreme stretch of
The ideal option would be to have some automated process for testing this. Any ideas how this could be done? Otherwise, I think we need to choose a reasonable set of things to support. After reading this discussion twice, I still do not understand what the cases are :-). @dsyme can you give us some authoritative matrix with what options are used on what systems? Ideally, we would support at least the latest Windows Phone & Windows 8 Tablets + Mono and .NET, but we might actually be able to get better mobile story with FunScript (I'm making some progress there). Silverlight would be nice for TryF#, but https://fsnotebook.net might be an alternative in not too distant future...
I would actually keep multiple One more reason is that I think having separate projects might be a good way to avoid |
I also tried using ? but I couldn't get it to work correctly. If you can get it to work it would be great to have several options
The ideal would be to have unit tests running on the different runtimes, but that's probably not as easy as it sounds. For starting, I think the best would be to create sample projects in Windows Store, Windows Phone & Silverlight that reference the portable version, get them in the tests solution, and make sure they keep working after we make changes to the type providers. I've started doing this, I'll add it to this pull request later this week. As for mono, I would expect the normal version to work as is, but we do have to test it. If someone can get a nicely packaged linux vm already with mono 3 and fsharp 3 already installed that would be great :) One other thing I'd like to do is to downgrade the main version from .NET 4.5 to .NET 4.0. There's only one method call specific to 4.5 (ReadToEndAsync), and it can be replaced without much effort. 4.5 doesn't run on a bunch of OS versions (like XP, Server 2008 R1, etc), and a lot of people can have it on their dev machines but can't add a dependency to it in their applications |
I found some more time to take a look at this. I think it would be good to follow Don's advice and avoid using quotations (and I wanted to look into the
I just want to make sure I'm not missing something... it might not be worth fixing if we decide to avoid quotations, but I wanted to check before I try making the changes... My current branch is here: https://github.com/tpetricek/FSharp.Data/tree/portable |
BTW: If anybody can explain what assemblies am I supposed to reference in portable F# library that would be very useful - I'm a bit confused at the moment. I know the right But when I wanted to add more code to the sample (like download data from the web), I was not able to get that to compile. Should I use assemblies from I tried |
I have some more bits that I haven't pushed yet, mainly some sketches of sample apps for the various platforms, but haven't had time to work on it in the last couple of weeks. The FSharp.Core.dll reference was working ok on my branch at the time, but I haven't merged back your latest changes and tested I haven't changed the tests to use the portable profile yet |
@ovatsus Hm, in that case, I'm probably doing something wrong. If you had some time to check the changes I did (or even merge your recent work), that would be great. I think it would be good to have some compiling portable library in the repository before we try changing the code (try rewriting it without using quotations). |
Hi, haven't forgotten about this, but haven't had time yet to merge or check your newest changes |
Hi, The last function in the file uses the
|
Nice, I'll try to use that instead of the quotations |
@tpetricek I finally got some time to work on this. I was able to merge your latest change and fix that error you were having building the portable libraries, but I'm not being able to get your ? operator working correctly. I'll finish the pull request with everything working with the quotations manipulation, and then we can try replacing that with the ? operator on a second step |
I got the portable library support working for almost everything, except for when a type provider needs to generate an expression that uses Some or None. I could workaround it by changing the api slightly so there's no optionals in the interface between the runtime library and the generated code of the erased types, but this is worrying. The problem is the following:
I get an exception saying portableOptionType is not a discriminated union.
I get an array of UnionCaseInfo correctly, and I can look for the Some in there, but then I can't call Expr.NewUnionCase because that union case is from the portable version of UnionCaseInfo, and the type provider is running the full .Net Any ideas? /cc @dsyme @tpetricek I'll try to push the code tonight |
Funny, I was just talking with @dsyme and Keith (kvb) who is writing some type providers and warned me that standard F# types (functions, options, ...) do not work nicely with portable types - just as you say! The workaround sounds pretty clever - would it work if the expression tree did not contain Expr.NewUnionCase, but instead directly called the (If you update the pull request with the latest code, let me know and I can take a look too.) Thanks a lot for the contribution, it would be really great to get the portable version out! |
Your suggestion worked :) PS: It's actually called Option.Some(123) and not Option.NewSome(123) |
When doing the recent work in a6dd98b, I tried to make some code in the CSV provider portable-friendly. I also improved the
A bit ugly, but it does the trick! |
I'm almost done, only missing the world bank provider. I ended up only using the ? operator only on places that already didn't use quotations |
I've pushed a new version. It's still not complete but it's getting closer.
With the current commit 1) works for CSV, JSON, XML, but not for WorldBank, and 2) works fully for CSV and partially for JSON and XML (array types not working) There are a couple of new projects under the samples folder. The WindowsStoreApp runs fine, but I'm not able to test the WindowsPhone8App project, because I don't have a WP8 device, and the emulator doesn't support my processor. I've also created a WindowsPhone71App project, but the only portable profile available for F# doesn't support it. While running I get the error IStructuralEquatable not found on mscorlib. F# 2.0 used to have a version of FSharp.Core compiled for Windows Phone 7.1. @dsyme is that also available on any way for F# 3.0? I'd really like to be able to use F# 3.0 to compile to this platform. @tpetricek I ended moving the whole StructureInference to the runtime assembly, but we might only need some parts. Also, a better name for the Importing module would be nice. In the process I've also make all the providers use readTextAtRunTime, so you can close #14 and #16 after this is merged. But please don't merge until at least 1) works for WorldBank I haven't figured out the problem with WorldBank yet, but I know what is the remaining problem in JSON and XML, just didn't have type yet to fix. The problem is the use of makeFunc that creates functions of the wrong FSharp.Core version. If you run FSharp.Data.Tests.sln while debugging FSharp.Data.sln you can see it throw an exception later on inside makeMethod. BTW, initially I changed all calls of makeMethod to your ? operator, as it looked nicer, but that delays errors, and makes it harder to debug, so I ended up switching to makeMethod again To debug, in addition to running two Visual Studios, I've added Test.fsx that shows the signature of the generated types and members. If [DESIGNTIME] appears anywhere in the output, then some type is still pointing to the wrong assembly @tpetricek I could use some hand to try to figure out what's the problem with WorldBank, which happens even on the normal profile. Just open WorldBank.fsx on the samples folder, and you'll see this error:
This error is different from all the others I've had before, it was usually something like "type T is defined in assembly FSharp.Data.DesignTime, please add a reference to it" PS: I did a force push, so probably if you try to merge to the portable branch git will get confused. In any cases, my commit was after all current commits, so there's nothing to merge further right now |
Added a sample for Silverlight also. Two things don't work:
|
…amespace to avoid collisions with erased types
… one of inner types needs replacement
The WorldBank provider now works correctly for the version with type provider arguments (e.g. WorldBankProvider<"World Development Indicators", Asynchronous=true>), but still gives the same error when using the version without arguments, which to me doesn't make much sense as they're almost exactly the same code. It's the only thing missing for this to be mergeable to main. |
The changes are looking great, I merged them into the portable branch to take a look and it seems to be working fine for me. Even though everything seems to be working fine, the quotation transformation code seems to be getting a bit complex (it would be great if you could follow the style used in the rest of the code and comment the top-level functions, it would be also nice to keep uniform indentation, at least within a single file, but that would mess up the history, so I'm not sure what to do). Do you think we should follow the advice by @dsyme and Keith and avoid using quotations in the long run?
The testing script that detects design-time types in signatures is pretty cool! Do you think it could be turned into something that can be executed as part of unit tests? (So that we can run some tests automatically.) I suppose this would be useful even if we switched from quotations (because there might still be a bug in locating the right type...) |
And thanks again for all the hard work on making this possible! I'm really excited about making this work in Silverlight (and elsewhere). Once this works, we should be able to run the documentation live in www.tryfsharp.org, which should make it even more attractive! I think once we finish this, we can mark it as a first mature release and move the main repository to http://github.com/fsharp |
I finally found what's the problem with WorldBank. It's some limitation in ProvidedTypes when you have a type provider with the same name of a namespace, it get's confused. I renamed WorldBank to WorldBankData and WorldBankProvider to WorldBankDataProvider, following the same pattern used in the Freebase type provider, and now it all works. Do you agree with that change? |
…o original namespace + Move back StructureInference to design time assembly, leaving only the minimum needed types + Make sure everything not supposed to be used directly is hidden under FSharp.Data.RuntimeImplementation subnamespace
I did a little bit of refactoring to make sure namespaces are consistent, implementation details are properly hidden, and to make it more close to the main branch. |
…sion & support for topics
The WorldBank provider is now also present on the portable version of FSharp.Data. There's no caching because there's no file access, but maybe later we can add and in-memory cache at least. I changed the implementation to use the JSON api instead of the XML api so there's no dependency on System.Xml.Linq for it (Silverlight doesn't have it) |
Excellent work! I'll take a look at the latest version and we can finish it & merge it on Friday. |
…to pass the culture to the json parser
…esn't need to be replaced but the inner generic argument type does
…ly inside csv + Add unit tests
…ullables instead of options
…-targeting to portable profile
Sorry, the last commits were on a local branch but when I pushed they went to master :/ Have to take a better look at git docs |
Support portable libraries (and lots of other changes)
I merged the pull request (so that we finally have all the changes in the master branch here), but I will review the changes tomorrow and may do a couple of changes here and there (so if you make some changes in the meantime, we might need to resolve some conflicts). If you can send one pull request per one issue or one logical change from now (from separate branches), that would be good, because it makes reviewing, discussing and accepting pull request a lot easier. Thanks! |
Don't merge this yet, it's still work in progress, I just want to discuss the approach before proceeding with the rest
I've taken a different approach compared to FSharpx and the Freebase type provider
In FSharpx we use FAKE scripts to reuse the same .fsproj for both the portable and normal build, but that hides errors until we run FAKE (which I usually forget). I've used 2 .fsprojs instead, it's a little more work because when we add a file we must add it to the two project files, but it's easier to make sure everything is working without having to leave Visual Studio
In the Freebase type provider, instead of using quotations and splicing like in all the other samples, the expressions are constructed manually because we need to reference the runtime assembly instead of the current executing assembly (the design time assembly). This makes the code much uglier because of all the reflection stuff. Instead of that, I've created a set of helper methods to traverse the quotations and do the necessary patching. It's still a little flaky, but at least for the simple expressions used in the csv provider seems to be working ok.
@tpetricek let me know what you think of this approach (ovatsus@29de451#L4R51) Are you ok with it? Do you think it might cause performance problems when compiling?