Closed catalin-hritcu closed 2 years ago
- version complexity: we regularly waste cycles trying to figure out which package we should require so
that the F# build works on mono, VS2017, VS2015... as far as I know, we haven't had comparable difficulties with OCaml
This is fairly easy to fix, most of the package issues regarding FSharp.Core etc. can be solved by using a tool like paket to handle dependencies. I'd be happy to contribute this myself, I wasn't aware that this was such a bothersome issue.
- build complexity: we have two maintain two build systems; I seem to recall the F# build has more constraints re. the dependencies across sub-projects
The build system is somewhat arcane either way - I don't have a good enough understanding of it to be able to contribute something alone, but F# has sophisticated tooling for build automation (eg. FAKE(https://fake.build/), ProjectScaffold(http://fsprojects.github.io/ProjectScaffold/), which might be worth migrating to, considering the current complexity of the build process.
- syntactic restrictions: there's a magic subset of F# and F that is unspecified; whether you write F# or F first, you're bound to be bitten by the other build once you need to debug your code -- I understand and appreciate that it's easy to internalize and forget once you hack on the F* compiler on a regular basis, but for people who are would-be contributors or occasional contributors, it might not be that natural to write in that subset
It probably wouldn't be too much effort to create a tool that could warn about this, and have it run as part of the build process. I'm skeptical of how much of a bother this part really is though - it's common for larger projects to have a strict code style, and it's not much trouble to get used to working in this subset, even without a specification of the subset.
- some language design decisions were informed by the need to retain compatibility with F#: 'a notation for type variables, but also namespace resolution rules, which in turn made dependency analysis and name resolution more difficult, with numerous iterations by e.g. Tahina to get it right -- I seem to recall (but correct me if I'm wrong!) that one reason why we can't have a lexing-only dependency analysis is because we chose to retain the same behavior as F# re. the current namespace
It's unfortunate to have to take language design decisions to retain compatibility with F#'s syntax - especially regarding things like namespaces, which F generally handles a lot better IMO. For example, F# can't handle FStar.Pervasives
and FStar.Pervasives.Native
in different files - whilst this is somewhat annoying when trying to get extracted F to work with F#, I think it's a worthwhile annoyance if F gets a better namespace mechanism out of it.
Some things like 'a
syntax could probably be handled by a preprocessor. I think that's a worthwhile trade-off to not clutter F's syntax. I've never found 'a
to be of much use in F* anyway.
Regarding F# compatibility, we depend heavily on being able to extract F# code and using the parser & prettyprinting components directly from F#. That said, having the sources written in the intersection of F#/F* isn't so important to us as long as we end up with dlls and a cross-platform executable. It is important that we are able to modify and test things quickly though, which includes changes to syntax, so even a bootstrapped approach might not be suitable.
In developing #1742, I encountered many nasty corners — the subset of F# that I was supposed to be writing is not documented at all! I had to edit NotFStar.Util.fs
in the process, and found that implementing nread
in "F# with OCaml compatibility" was a pain — the CI runs the fstar-in-fsharp
target, which I think is unnecessary in the long run. There were numerous compile errors that weren't caught at the source level, and only caught after the OCaml extraction finished; these were very painful to debug — one of the primary issues is that I had to duplicate all types written in the .fsi
in the .fs
as well; code duplication makes coding highly error-prone. Finally, there were runtime crashes because there's no way to tell if I'm exhaustively catching all exceptions — I think runtime crashes are unacceptable in a modern programming language.
Incidentally, many of @aseemr's woes from the Slack discussion will be over when the long tail of #1742 is finished — working with zero editor support can lead to many wasted cycles during development; that's the motivation to develop fstar.exe --lsp
in the first place. The first steps in the roadmap I propose are the following:
.fs
, .fsi
, .fst
, .fsti
files from vsfstar
and fstar.exe --lsp
, but no theorem proving support at this stage. Develop it with first-class support for FStar.git
.vsfstar
) for all editors used by the development community to use fstar.exe --lsp
, and get everyone fully migrated so nobody misses VS. For pure F* code, fstar-mode
is still the best option at this stage.fstar-in-fsharp
target; people can still use it locally at this stage.aseem [1 month ago] F* CI build already bootstraps the compiler using the checked-in OCaml snapshot (edited)
The relevant lines from src/Makefile
are:
fsharp-build-and-test:
+$(MAKE) fstar-in-fsharp
+$(MAKE) fsharp-unit-tests
# The first tests have to be performed sequentially (but each one may use some parallelism)
# Adding the F# build and F# tests also here
# since in the uregressions target it may not be a good idea to override the fstar.exe binary?
utest-prelude: fsharp-build-and-test
+$(MAKE) boot-ocaml #build the ocaml-snapshot
+$(MAKE) clean_extracted #ensures that there is no leftover from previous extraction
+$(MAKE) fstar-ocaml #extract the compiler again and build the result
+$(MAKE) ocaml-unit-tests #run the unit tests
+$(MAKE) fstarlib
Ping. I implemented support for typechecking F* source files in emacs (using makefiles) and have been exclusively using it for past 3 months. It provides symbol lookup etc. and is good enough for me. With incremental bootstrapping support, I also don't rely on F# builds for quick testing anymore.
Happy to revive this discussion (and see if we want to decide either ways for v1).
I remember there was a conclusion reached during one of the F* meetings. Can an update be posted here?
Transcribing a slack discussion here:
@aseemr wrote:
@nikswamy wrote: on F# dependence: I'm also in favor of leaving it behind. But, it would be great if we could restore F# extraction before we do. Otherwise, there are people using F* on .NET who would be abandoned
I think there are people who use F* today without any dependence on OCaml, e.g., just by building the sources in F#. If we still want to support that, then we need a way to produce an fsharp-snapshot of the compiler
@aseemr: it seems important to me (to continue supporting such users)
@protz it seems that people who use the F# build of F* are on windows, correct? for those users, wouldn't a binary package be equally well suited?
@nikswamy yes, a binary package would work ... but then we should get good about producing binaries regularly. not sure what the status of our nightly builds are
@catalin-hritcu they seem to be working fine since our last release (which seems like a record)
@nikswamy nice
Separately, I recall us discussing that we should post prominently here, on the mailing list, on zulip and slack, indicating that we are considering leaving behind the ability to build the F* sources in F# and to see if there are any users out there who are relying on this feature in some way that we have not anticipated.
For starters, @A-Manning, what do you think about this?
I think there are people who use F* today without any dependence on OCaml, e.g., just by building the sources in F#.
I wouldn't want to lose the ability to compile the F sources as F#. It's really helpful for projects that use F from F - for example, I often use FStar.Parser
and FStar.Pprint
from F# to generate F files. Migrating to OCaml would not be practical, unfortunately.
it seems that people who use the F# build of F* are on windows, correct? for those users, wouldn't a binary package be equally well suited?
There are quite a few of us using the F# build on Linux/OSX, and a binary would not be well-suited to those that have F* as a dependency.
Done as part of #2512.
We recently had a Slack discussion on the pros and cons of dropping the current requirement that the code of F* has to be valid F#. Fortunately, I saved this right before it went dodo.
@nikswamy @aseemr @protz @tahina-pro @mtzguido: Let's continue any discussions on this by commenting on this issue!