-
Notifications
You must be signed in to change notification settings - Fork 301
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
[All languages] - Universal package management approaches #3089
Comments
Hello @alexswan10k, I don't understand what you are suggesting. Something important with Fable is that it live inside of F# ecosystem and Fable is not an independent language. For example, Fable doesn't really compile or resolve dependencies (I simplify I know). It is the F# compiler which does it, then generate the AST and Fable kicks in from this step. Distributing the Fable libraries via NuGet allow you to have access to all the F# tools for free: IDEs, analysers, linters, formatters, etc. Currently, there are mainly 2 scenarios when distributing Fable libraries:
I don't see why targeting another language other than JavaScript would not work the same way it does with JS. Fable 3 and 4, emits files on the disk so it is as if you wrote them manually. It is true that if one of the library you use depends on a target libs (like React, Express, etc.) then you need to install both the Fable NuGet + the target lib via the your preferred dependency manager (NPM, Yarn, Cargo, LuaRocks, etc.). Having our own dependency manager would mean having to fork or adapt the existing F# ecosystem, change how F# works so have a custom compiler, make adaptation to IDEs, and a dependency manager is a really complex piece of software to create and maintain. Especially if you want to be multi target. In the past, deciding to embrace the JavaScript ecosystem tools and standard has always proved to be of a huge benefit for Fable. And I do think, the same will be true for others languages. IHMO the current position of Fable, allow it to benefit from both F# tooling and target ecosystem tooling for "free". And allows, us to focus on only the specific job of Fable which is translating the F# to language X. |
If a library is written using pure Fable compatible code it will works across all the target language the same way. For example, if my library consist of: module SimpleMath
let add a b = a + b and I ship it to NuGet. I will be able to consume it for JavaScript, Rust, Python, etc the same way. If needed compiler directives can be used to make adaptation depending on the target language: let log msg =
#if FABLE_JS
console.log msg
#endif
#if FABLE_Python
print msg
#endif |
Hi @MangelMaxime, I do apologise I think my knowledge on this may be a little stale, as this has flip-flopped a couple of times over the lifetime of Fable. I have updated the original ticket to reflect your observations. So it does appear that F# code can just be distributed with a Nuget package, and compiled by the consuming system on demand (a little similar to the Cargo approach, but without internal knowledge of modules). Assuming the target language has working module support, this should just work out of the box as you pointed out. This is a pretty good place to be if so. I guess maybe the real question then is around refining the user experience of authoring and finding these packages as mentioned here. It was not obvious to me where nuget libraries support or do not support Fable (and which would be language agnostic), which is a fundamentally different ecosystem than .NET. |
No problem, it is true that it changed several times. The NuGet distribution is here since 3 years I think and has been pretty stable since them.
I still think that not much can be done on this side. Right now creating a Fable package is just about adding: <!-- Add source files to "fable" folder in Nuget package -->
<ItemGroup>
<Content Include="*.fsproj; **\*.fs; **\*.fsi" PackagePath="fable\" />
</ItemGroup> to the For pure bindings, nothing special is required.
There has been some initiative in the past:
However both of them require a manual editing and UX is not that great. IHMO, the good solution would be use tags when authoring Fable package: <PackageTags>fable;fsharp;json;fable-js;fable-python</PackageTags> And then have a website/tool which send search request to NuGet.org server.
I would vote for "not important" because I don't think I encounter this problem in the past. 🤞 |
Thanks for this, it fills in a lot of gaps. It looks like most of my concerns basically have solutions today, it's the age-old documentation problem of "you cannot search for what you do not know about" I guess. I noticed a lot of these details are documented too, which is great. I just had trouble finding them. I could not find https://fable.io/community/ though from the main site. The tagging/nuget api query on tag solution seems like an excellent idea to me. |
About https://fable.io/community/ it never really worked and when merging "Awesome Fable" with the rework of fable.io Alfonso and me kind of agreed on making it deprecated. Because, it would mean that we need to maintain the list of items manually in 2 different places and also it doesn't fit the look right now and would require work etc. IHMO, if something is to be done or happen it is to experiment with the tagging/nuget API. Because, this would also a single source of truth without any work require from the maintainers. And also, the experience can be deeply customized if needed. |
Thank you @alexswan10k for your questions and thoughts, and thank you @MangelMaxime for your detailed response! My personal opinion has always been that |
Thanks, both, and I do agree with reusing the F# ecosystem where possible etc. I guess I am also just aware that there are limitations due to external constraints such as .NET dll loading behaviour (everything global), which will forever put F# at a disadvantage against its competitors that have a more modern package management philosophy (locally scoped packages eg npm or Cargo). This is absolutely not a Fable problem though, it just turns out Fable is not theoretically constrained by these shackles, which is an opportunity in my view. Anyway, nuget querying seems like an obvious place to improve matters. Perhaps I can take this away and have a look at crashing out a page for integrating with https://api.nuget.org/v3/ for the fable.io site. I imagine this should be pretty straight forward, and can probably be done through the public api, and thus be entirely client side. I will report back.. |
Looks like it is possible Nothing is using tags at the moment, so we might want to fallback on using query as a stopgap. I will put some UX fluff around it anyway. How would one host something like this in the core site? It looks pretty much markdown-only from a cursory glance. Can we run react components? Edit - Looks like you cannot query tags according to the api docs. You can query packageType though. Is this an option? |
@alexswan10k I don't see why not, but existing Fable packages will have to be republished with a package type so they can be discoverable this way. Also, I don't see package type listed anywhere in the existing UI on |
For hosting, it can be done two ways. Either inside the current site, because we can generate HTML or load JavaScript on a specific page. For example, this page from Fable.Form is just using the doc generate to have the navbar generated and all the page content is actually an SPA. Or, we can create a new repo inside of fable-compiler org to host it separately. For example, The benefit of the first solution is that the navbar and style are handled by Nacara (doc generator) and so it will easy to have the same look and feel between that and this specific page. The cons is that the repo will not contains simple documentation anymore but also the source code for that search packages page. IHMO, it is better to host that specific page/section under it's own repository. It will make it easier to accept contribution, prototype stuff, and if necessary deviate from the standard styles to improve the UX. We just need to use the same color and basic style to have a consistant look and feel. |
Thanks everybody for your comments! Yes, as @MangelMaxime and @ncave say we should likely avoid trying to build our own package manager and reuse existing infrastructure instead. Package management is one of these deceiving problems that are much more complicated than they look at first, as Paket maintainers can corroborate ;) However, if we can do something to improve the experience of Fable users, particularly around discoverability as @alexswan10k says, that'd be great. Some notes:
|
Thanks all for the input. I have been pushing forward the discoverability angle, and I think I pretty much have a working search page (using tags after all) that talks to the nuget api. The big problem now is going to be agreeing on all the tags, and getting package authors to correctly follow the convention :) I propose the following convention for tags:
This convention could also be extended to cover bindings
Here is the working page: Editable: I crossloaded the bulma stylesheet from fable.io by the way, so perhaps not the most elegant, but it gets the same component styles and colour scheme etc for free. It is pretty rough around the edges right now, but hopefully, the intent is self-explanatory. We can always do more polishing down the road. Happy to take direction from here, let me know. Should I make a repo? |
I find that Personally, I would go with:
UX related:
See I think we should decide on a height and make the logo adapt the best it can to that height.
This is fine for the first text "This will search Nuget.org for any packages with the following tags" but for the main content I don't think this is good. I wonder if we could use a similar style as for the Blog list for the boxes or if that would be too heavy. |
Updated as per feedback https://github.com/alexswan10k/fable-nuget-search |
FYI: Femto already supports Python packages 🎉 https://twitter.com/zaid_ajaj/status/1567101357470978053 |
Thanks to the work done by @alexswan10k I think we can say that it is possible to search for packages using the NuGet API. We can move the discussion to https://github.com/fable-compiler/packages I created an issue with a specification proposition: fable-compiler/packages#1 About the design/UX of the tool itself, I have some ideas how we can improve what has been started by @alexswan10k. |
Great. Thanks @MangelMaxime. Do let me know if you need me to move anything, transfer access, host, or whatever.. Looks like it the target repo is empty? Maybe it is just that old eventual-consistency thing :) Will check back in a bit. |
I just created the repo to have a place dedicated to that tool and especially for the hosting the specifications etc. I have not started yet to upgrade/write the tool itself yet. |
With the Rust/Dart/Python targets becoming less immature by the day, it has got me thinking... Perhaps it is time to revisit the package management/distribution debate in the light of an approach that could work for all targets.
I am not an expert on any of this, so hoping those that know these systems inside-out will be able to chime in and correct me where I am talking rubbish! I will go back and update this post as new info comes in.
State of the world today
Nuget packages ship binaries only by default. This is not compatible with Fable. In order to make a library compatible, F# sources need to be included, which can then be compiled by the consumer. This is somewhat of a manual process, but there is an interesting discussion on improving this here #2939. Discoverability is also quite limited
https://fable.io/docs/your-fable-project/author-a-fable-library.html
https://fable.io/community/
https://fable.io/resources.html#examples
Previous discussions
#1649
#856
#2939
I should also mention Femto at this point, which already bridges the impedance mismatch between ecosystems (npm/yarn vs Nuget/Paket) in order to create a more unified experience. This approach seems to be valid for bindings.
A brief summary of target ecosystems
Each compilation target generally has its own ecosystem for managing dependencies.
Some other hypothetical examples that may help generalize the approach
Frustrations with Nuget/Paket and the .NET ecosystem
One of the core pain points many developers hit eventually is the transitive dependency collision problem. This happens when you have something akin to the following dependency tree:
Nuget - Do I use V2 or V3? If you use V3, it breaks Dep A, if you use V2, it breaks Dep B. Checkmate!
Due to the fact that nuget is heavily opinionated on how the .NET CLR loads dll's, it forces the world-view that all libraries are global, and thus there can only ever be 1 source of truth when referring to a namespace/type. Although this is less of a problem in F# because dependency tree's are generally less deep, this seems to me to be a fundamental flaw which is unlikely to ever have a good solution at the .dll level. This puts limits on the complexity of libraries, and their ability to reuse existing code.
More modern ecosystems (such as js - npm and Rust - cargo) get around this problem by supporting scoped, or aliasing of package names, and referring to packages in code by their aliased name.
Questions
The text was updated successfully, but these errors were encountered: