-
Notifications
You must be signed in to change notification settings - Fork 310
Description
So far there have not been many good news in 2020 so let's to make one by releasing a new major version of Fable 3 π I'm collecting different threads from recent issues here to list the features that could go in Fable 3:
Reflection support
My original hope was that #1839 would basically become Fable 3, but I've left too much time passed, the PR has lost sync with master and it's proving a bit difficult to make it work now. Besides I had some concerns about its reflection support. Although it's very interesting to be able to access to all class methods, constructors, properties and attributes (currently Fable is limited to record, union and tuple fields) for scenarios like test generators (I'm also using reflection now for interacting with databases in Node with good results), I'm concerned about how this would affect the resulting bundle in web apps.
Fable tries to play well with tree shaking in JS. For example class methods are not attached to the objects and can be removed from the bundle if not actually used. However, if we keep references to the methods in order to be able to call them through reflection, tree shaking won't be able to tell unused code apart (e.g., see this comment about Dart).
In some quick tests, the increase in the bundle size was not much, but I'm not sure if reflection wasn't used much in those cases. When you include support for quotations the bundle size explodes and it could be because reflection is used more intensively.
I'm considering now to give support to Constructors, Methods, Properties and Attributes, but only through special helpers in Fable.Core.Reflection module that generate the information in compile time only where it's needed (same way as we can only get type info when the type is known at compile time). Like:
open Fable.Core
let cons = Reflection.generateConstructors<MyType>()
let methods = Reflection.generateMethods<MyType>()
let meth = Reflection.generateMethod<MyType>("Foo")
// For example, this would be replaced in compile time by
// an array with the attributes decorating the type
let atts = Reflection.generateCustomAttributes<MyType>()
Would that be a good idea? The main downside is there could be duplicated code if we make the same call in multiple places.
Quotation support?
This also depends on #1839 Not sure how difficult would it be to add quotation support if we implement reflection differently.
Mangling abstract members
See #2068. Basically, right now we cannot implement two interfaces with the same member name in Fable. If we want to allow this we need to mangle the member names so they don't conflict when attached to the object prototype. But then interfaces used to type objects from JS would have to be decorate with an attribute like NoMangle
or similar.
This would be the main breaking change in Fable 3, but we could have a transition period.
Type testing
The main limitations of type testing and Fable atm are:
- no type testing of generics (see RC4 - DList isn't fully Fable compatibleΒ fsprojects/FSharpPlus#307 (comment))
- no type testing of interfaces.
For generics maybe we can try injecting the name of the generic arguments in the constructor of generic types (something similar was done in Fable 1) although we would still have issues with types that translate directly to JS counterparts like arrays or mutable dictionaries.
The main reason for not testing interfaces was they might represent objects from JS, but if we're going to restrict this to interfaces decorated with NoMangle
in Fable 3, we could add the name of implemented interfaces to F# objects (again, something similar was done in Fable 1).
Plugins
See #2066 and fable-compiler/fable-react#196
Magic?
@ncave is up to something, we just don't know what yet π