Fable icon indicating copy to clipboard operation
Fable copied to clipboard

[Snake Island] Discussion: Release of Fable 4

Open alfonsogarciacaro opened this issue 1 year ago • 45 comments

@dbrattli and I were commenting whether releasing a "stable" Fable 4 version would encourage more users to try it out. Not sure if it will help or not, but in any case we should start discussing how the release process should be. So I'm opening this issue to share ideas. Some thoughts from my side:

  • The main "technical-only" argument to keep Fable 4 in alpha/beta is the AST. It's been several weeks since there haven't been changes in the AST. If everybody is happy with it for now we could "lock" it and start updating existing plugins so JS users can also try out Fable 4.

An alternative to avoid having to lock the AST would be to bake-in the plugins most used (I think it's basically Feliz.ReactComponent) and deprecate plugins for Fable 4 so we still have freedom to make changes. But probably we should avoid that.

  • In principle Fable 4 won't have many changes for JS users, but there are many internal changes so we want them to upgrade as quickly as possible to avoid having to maintain Fable 3 for a long time.
  • Should we add features for JS users so they've incentive to upgrade to Fable 4? Right now we have JSX, but not sure it will be enough. One thing we could is improve Typescript compilation so Fable can be used within a Typescript project. This has been sometimes requested by users.
  • How will we number versions from Fable 4 on? I haven't been very strict with semantic versioning, but if we want to have a new minor version every time one language has a new feature, other languages will have minor version bumps even it they stay the same (maybe it doesn't matter, as I think with dotnet tools devs don't usually use version ranges).
  • If Fable 4 "stable" comes out, does this mean all languages are "stable"? If not, how can we specify that? Displaying different versions on start depending on the selected language?
  • Should we have a common roadmap instead? Jump all languages to beta, then to release candidate and then to stable when we are all happy?

alfonsogarciacaro avatar Aug 01 '22 10:08 alfonsogarciacaro

I think a release could help the usage for Python. You should be able to try it out without having to specify a version for dotnet tool install fable. This makes it easier to talk about it at conferences. I will be presenting Fable Python at NDC Oslo late September. So it would be great if we could make it a little less experimental till then.

If we keep a single version then all languages also needs to bump major version at the same time which means that breaking changes needs to be synchronized using a development branch (like we have now with snake_island). Bumping minor versions without any changes for some languages should not be a problem.

If we keep separate versions for each language then they should probably release separately as well. Having separate version numbers and releases inside a mono-repo like Fable makes things complicated and confusing. I think we should try to avoid it.

It would be easier to have a single version, and then tag each language as alpha, beta, rc or stable. This means that e.g Python could be part of Fable 4, but when you select --lang py then you see Fable: F# to Python compiler 4.0.0 (beta). So Python could move from (alpha to) beta and become stable without having to release Fable 5. Php could stay in alpha or even be labelled experimental if we feel it's unsupported. I would also prefer if we could automate publishing so version numbers are set using Git tags, then when generating a release in GH a publish action will auto-publish all the packages, even upload a new fable-library Python package to PyPI. Changelog update should also be automated using GH instead of the manual entries we have today. If not then every commit of relevance also needs to include an update to RELEASE_NOTES.md. But again, we should try to automate more of these tasks.

I see the problem of releasing Fable 4 without enough new features for JS developers wanting to upgrade. But having long lived branches (1.5 years) is a problem in itself. So it's better to release more often, get it out, and set a deprecation period for Fable 3 for as many months as you are comfortable with maintaining it. We should not invent more features now so adding new features for e.g TypeScript needs to wait for Fable 5 if they require breaking changes.

So imo we should release Fable 4 as soon as possible. Language maintainers should to decide if their new language should be tagged as experimental, alpha or beta. I could be willing to move Python to beta. It's missing some features, but that is not a problem. The only problem I can think about is the handling of integers which needs fixed in a better way (since Python only has arbitrary large integers)

dbrattli avatar Aug 02 '22 07:08 dbrattli

It would be easier to have a single version, and then tag each language as alpha, beta, rc or stable.

I agree with all @dbrattli said above. Rust support is definitely still alpha, but we're making good progress towards stabilizing it.

ncave avatar Aug 02 '22 07:08 ncave

Makes sense. I concur Rust support is definitely still alpha, although progress is being made. It would be good not to hold up everything else though.

Before the AST is declared stable, I did want to check something. Previously we were keen to support pass by ref as an attribute on a function parameter also, as there are quite a few limitations with the explicit inref approach (no pipelining, closure capturing, etc). I couldn't get it to work because the AST did not have function parameter level attribute info. I know there was talk of adding this in, was any progress made on this?

Also with respect to full typescript support, my 2 cents.. This would be a big win in my book. If you are writing an api surface, or package which is either hosted on npm, or consumed by typescript as the root app harness or part of a larger application, having type information would be a huge plus and could encourage incremental adoption. We have a similar problem in the Rust domain, where solving interop comprehensively from the F# side is an insurmountably hard problem. Thing is - Rust has it's own type system, so why not let Rust do what it does best, and integrate with its own api's and form the glue? The same logic applies to any typed language, especially if it has its own package ecosystem. This lets you use F# incrementally, and focus on what it does best - high level domain logic and modelling with less code and complexity than its peers.

alexswan10k avatar Aug 02 '22 16:08 alexswan10k

Thanks a lot for your comments, then let's aim to release Fable 4 mid-September before NDC Oslo... or you can release it at the conference itself if you want some on-stage effect @dbrattli ;) I'll lock the AST, update the plugins and ask users to test it out with existing JS projects to make sure there are no regressions.

As agreed, we'll have a common version but different "status" per language. Probably we cannot do much with Typescript before the end of September, but we can move it from "experimental" to "alpha" to make people know we're planning to make it a fully working target.

alfonsogarciacaro avatar Aug 05 '22 07:08 alfonsogarciacaro

Previously we were keen to support pass by ref as an attribute on a function parameter also, as there are quite a few limitations with the explicit inref approach (no pipelining, closure capturing, etc). I couldn't get it to work because the AST did not have function parameter level attribute info. I know there was talk of adding this in, was any progress made on this?

@alexswan10k After #2933 you should be able to, now compiler includes a GetMember method that works similar to GetEntity. So you can get the full Member info (including param attributes) from a reference in the calls. But please let me know if it doesn't fit your needs.

alfonsogarciacaro avatar Aug 05 '22 07:08 alfonsogarciacaro

Amazing. I will look into it and try get that last piece working. Many thanks, @alfonsogarciacaro.

alexswan10k avatar Aug 05 '22 07:08 alexswan10k

Thanks @alfonsogarciacaro. I'll start to fix the Fable.Python documentation which will be needed for any type of release. Fable.Python is almost 1500 passing tests now (incl. applicative). Still missing quite a few .NET related stuff but the language translation itself is quite impressive now. I'm pretty sure we could compile Fable.Standalone if it wasn't for the stack overflow problem 😅

dbrattli avatar Aug 05 '22 08:08 dbrattli

@dbrattli

if it wasn't for the stack overflow problem

Do you mind opening an issue for it for discussion, or pointing to an older discussion if there is any? We already have some trampolines in Fable at the cost of some performance.

ncave avatar Aug 05 '22 14:08 ncave

Definitely releasing a "stable" Fable 4 version would encourage more users to try it out, I think and I would be the one.

In fact, now, I'm trying to install Fable4, reading Announcing Snake Island (Fable 4) Alpha Release

Hopefully you're now as excited as we are! You can give Snake Island a go right now by following the instructions for each language above or installing it locally specifying the snake-island version range:

dotnet tool install fable --local --version 4.0.0-snake-island-*

This command does not work for an unknown reason to me: zsh: no matches found: 4.0.0-snake-island-*

I used to be a C#.net programmer since net.1.0, and have been a JS/TS functional programmer for decades, and now looking at brand new.net6, I decided to start using F# as my main language.

I tried to establish my FP style in Rust and Dart, but failed with lots of frustrations, one of my main reason to try Fable 4 is I want to see how higher functions such as Functor/Monad in F# will be transpiled to Rust and Dart.

So I tried to install 4.0.0 alpha, but failed, so will anyone tell me what is the proper procedure to start? Thanks.

ken-okabe avatar Aug 19 '22 08:08 ken-okabe

@stken2050

In your case, the problem is coming from zsh it is trying to interpret the * instead of executing the given command.

You can either modify zsh to not do that or provide the full version:

dotnet new tool-manifest # if you are setting up this repo
dotnet tool install --local Fable --version 4.0.0-snake-island-alpha-020

MangelMaxime avatar Aug 19 '22 08:08 MangelMaxime

@MangelMaxime

Oh, thanks a lot! It works, also kind of you to mention the zsh incompatibility that I did not aware of.

I use zsh in Linux, and zsh has been the default shell instead of bash since 2019 macOS Catalina, so I guess it would be preferable to offer the zsh compatible command in future README.md.

ken-okabe avatar Aug 19 '22 09:08 ken-okabe

@stken2050

I use zsh in Linux, and zsh has been the default shell instead of bash since 2019 macOS Catalina, so I guess it would be preferable to offer the zsh compatible command in future README.md.

The is that it depends on how your zsh is configured not everyone will have this issue.

And I think Alfonso wrote the command like that so people can always get the latest version.

MangelMaxime avatar Aug 19 '22 11:08 MangelMaxime

@MangelMaxime Ok, thank you. I will investigate my zsh configuration, then.

ken-okabe avatar Aug 19 '22 15:08 ken-okabe

Ah, sorry! Yes, I forgot about the issues with the * in some shells 🤦 Does quotation help?

dotnet tool install --local Fable --version "4.0.0-snake-island-*"

And yes, I used the start because we're releasing multiple snake-island version with bug fixes, so I wanted to be sure users always got the latest version.

alfonsogarciacaro avatar Aug 22 '22 01:08 alfonsogarciacaro

It works on my second try.

dotnet new tool-manifest  
dotnet tool install --local Fable --version "4.0.0-snake-island-*"

image

I think it would be nicer to mention to add dotnet new tool-manifest because, without it, it does not work.

ken-okabe avatar Aug 22 '22 01:08 ken-okabe

Thanks for confirming @stken2050! I will update the blog post so your experience can help other users :+1:

alfonsogarciacaro avatar Aug 22 '22 01:08 alfonsogarciacaro

@dbrattli @ncave @alexswan10k I'm planning to publish Fable 4 beta soon so users can start updating their projects and making sure there are no regressions. I'll also write a blog post to explain our decision of having different status for each language in the same Fable release. I assume the status for Python is beta, can we move Rust to beta too? Roughly this is how I understand each status (please let me know if you want to modify some of the definitions):

  • experimental: included for experimentation, but it's currently not maintained and it may be removed in the future (php).
  • alpha: not in working state but it's in the roadmap (we'll move typescript from experimental to alpha).
  • beta: missing features but in working state, we don't expect big changes in the interop mechanism (changes in code generation are always possible in Fable), community feedback is crucial at this step (python, dart, rust?).
  • stable: working state and most features that are currently possible for JS target implemented (we should add more columns to this table so users know what's implemented for each language).

alfonsogarciacaro avatar Sep 01 '22 02:09 alfonsogarciacaro

@alfonsogarciacaro Thanks for all the work with making Fable 4 ready for publishing. I agree that Python can be moved to beta. It's missing features, but the working state is really good (imo).

dbrattli avatar Sep 01 '22 07:09 dbrattli

@alfonsogarciacaro IMO I'm not sure alpha means "not in working state", perhaps we can replace the "working state" language with feature-based: less features (alpha) vs more features (beta) vs full-featured (stable). I'm not sure yet how to quantify the feature percentage that will make Rust "beta", perhaps we can define milestones so when we reach certain feature completion we can move Rust to "beta". But that's just one view, I'm quite open to other interpretations if someone disagrees.

ncave avatar Sep 01 '22 09:09 ncave

I was thinking in what users should expect more than in the number of features, like:

  • experimental: give it a try if you want, but we are not currently planning to work in the target
  • alpha: give it a try if you want, we are planning to work in the target but there are many things missing
  • beta: please do try it, some features may be missing but we need user feedback to improve the target
  • stable: we think the target covers enough F# for simple/medium/complex projects, we will provide support for bug reports and we won't introduce breaking changes (mainly for interop) without releasing a major version

But it's true naming is difficult and other people may understand the terms differently, so we can change them if there's a better solution. I personally would consider Rust still alpha if you're still discussing interop with basic types (e.g. if somebody writes some bindings but then the way string is compiled changes, the bindings may break), otherwise I would consider it as beta as there are already a couple of working examples and it's possible to write a simple project compiling to Rust (like this one).

alfonsogarciacaro avatar Sep 01 '22 11:09 alfonsogarciacaro

I am with @ncave on this, not sure I feel we are quite at beta yet.

My personal understanding of the difference between alpha and beta is stability, where alpha means mechanics and api's are likely to change drastically. There is definitely progress being made here though, and I think the move to creating thin wrapper structs helps significantly with exposing ourselves a stable public API surface, whilst not being committed to decisions around how these types are represented under the hood. This still does not cover everything built in yet, so I envisage there will still be some churn before all this is hammered out.

The intent is also that these wrapper structs will get their own interop trait implementations (Iterable, PartialEq, etc) where it makes sense, so it should behave just like a normal Rust type, but this is also a work in progress.

Looks good though other than that!

alexswan10k avatar Sep 01 '22 12:09 alexswan10k

In order to move languages quicker up the status-ladder we could also say that sub-components may have a different status than the language itself. E.g from the Stability of Kotlin components:

Stability of subcomponents

A stable component may have an experimental subcomponent, for example:

  • a stable compiler may have an experimental feature;
  • a stable API may include experimental classes or functions;
  • a stable command-line tool may have experimental options.

We make sure to document precisely which subcomponents are not stable. We also do our best to warn users where possible and ask to opt in explicitly to avoid accidental usages of features that have not been released as stable.

dbrattli avatar Sep 03 '22 07:09 dbrattli

I haven't been very consistent using it but in principle we have the Fable.Core.Experimental namespace for this. Although I'm actually trying to reduce experimentation in latest versions. Fable "features" can be roughly divided in 3 categories:

  • F# features: these are always very stable so the only choice for Fable is support or not support.
  • Interop features: there's room for experimentation here, but in most cases we cannot break interop to keep compatibility with existing bindings (this is why we have so many ways to import things 😅) .
  • Fable-only features: before I did more experimentation in this are (e.g. the Inject attribute) but I'm trying to avoid it now, because it makes Fable "fork" the F# language.

alfonsogarciacaro avatar Sep 05 '22 01:09 alfonsogarciacaro

And, of course, another solid way of measuring progress is the number of .NET tests passed as a milestone. As of 2022-09-05:

  • Fable JavaScript - 2290 tests passing.
  • Fable Python - 1511 tests passing.
  • Fable Rust - 1078 tests passing.
  • Fable Dart - 1052 tests passing.

ncave avatar Sep 05 '22 14:09 ncave

@dbrattli @ncave @alexswan10k

We've entered "theta" phase :) As discussed above this only affects JS. I will write a post about it but the idea is users start to upgrade their projects so we can make sure there are no regressions. After we receive some feedback if there are no major issues we can release 4.0 so users don't need to install prelease versions in order to test other languages.

@dbrattli Not sure if everything will be ready by the time of your talk at NDC Oslo, but let me know if you want to release on-stage so we can try to speed up things.

I'd also like to release Fable.Core 4.0 in the upcoming days so new libraries can depend on it for the JSX features. Is it ok with you or do you expect some breaking changes? (You can still add things after releasing, although as usual it's better to keep Fable.Core minimal).

Why "theta"?

I wanted to make the version name shorter to make installation easier, so I released 4.0.0-beta-001 but it happens Nuget sorts prerelease versions alphabetically so all 4.0.0-snake-island-* release were considered "more recent" 🤣 There were not many options after "s" so I picked theta, I hope that's ok.

alfonsogarciacaro avatar Sep 09 '22 04:09 alfonsogarciacaro

Fantastic 😊 to see this happening @alfonsogarciacaro. "Theta" is clever and sounds really good. I don't expect any breaking changes with Python. It would be great if we could release in time for NDC, but it's not a must. Developers will now be confident that this is really happening, and that Fable 4 is not going to be just a side branch or in -alpha stage forever. I have a bit of time for the presentation (60 min) so I have time to talk about the new Fable 4, and the different language targets. Show the new repl etc. Then dive into more Python specific stuff. If we get ready to release on-stage then I'll do it!

dbrattli avatar Sep 09 '22 06:09 dbrattli

We've entered "theta" phase :)

@alfonsogarciacaro Good choice, getting into a deep meditative state to focus our attention on releasing ;)

j/k, I agree it sounds really good!

ncave avatar Sep 09 '22 07:09 ncave

Exciting :)

I actually have a reasonable-sized F# codebase sitting on Fable 3 at the moment I can test this on (js output of course), so will upgrade shortly and do a regression run. I don't envisage any issues but will be sure to report back if so.

Edit

All seems to be working. A couple of bumps in the road with package version mismatches but nothing directly attributable to Fable. I did notice something seemingly weird going on when HMR changing files behind lazy loaded chunks, although this could have been something out of sync.. will investigate further but either way not a dealbreaker.

It also seems to build a LOT faster. nice.

alexswan10k avatar Sep 09 '22 08:09 alexswan10k

@alfonsogarciacaro I could really use a -theta-002 release since I have a some libraries, PRs and demos that are waiting for upstream Fable fixes. Would you like to make one? I could do it myself, but I think we should perhaps be a bit stricter with the releases now that we are out of -alpha so I'm trying to be a bit careful. Please let me know what you think. UPDATE: I'm releasing it

dbrattli avatar Sep 11 '22 12:09 dbrattli

I like to mention, that the online REPL shows currently mostly examples in JavaScript.

I assume, it could also present translated code for all the new languages.

I am missing a representation of the new targets, both in the README and on the homepage.

A blog post, that mentions the specific support for any language and some examples could also be helpful.

P.S: I also think it could make sense to sync the version of Fable with that from .NET and F#.

ShalokShalom avatar Sep 12 '22 23:09 ShalokShalom