Closed 21c-HK closed 7 years ago
@gregoryyoung We use FAKE scripts in almost all builds but it results that from 20 devs it is only me who changes something there. Max what the others want to do is to comment out the Test target. SAD!
@alexeyzimarev that is also happening if you use a different technology. People often tend to say "it's not my responsibility to get that working" and just leave it. I think it's more a problem with how the people in a team organize than with technology.
Regarding F# project files, would it be possible to create an F# project format which gets translated to .fsproj using FAKE which then gets built using MSBuild?
Yes it is possible ;]
VS support is a problem.... as always
I like the idea of having a F# DSL (or data structure) to describe the project structure of an F# project. Clojure (leiningen) for example uses a project file written in Clojure (S-expressions) for defining the project structure.
We can even do better by incorporating F# type providers into the project definition process, for example to use a file type provider to get IntelliSense for file paths.
@Krzysztof-Cieslak has a blog post with some ideas of how a custom project file could look like "Creating custom project file for F#" in case someone missed it.
The problem with custom project system is always tooling. We can't even get the MSBuild ones working properly...
Am 27.03.2017 10:39 vorm. schrieb "Tobias Burger" <notifications@github.com
:
I like the idea of having a F# DSL (or data structure) to describe the project structure of an F# project. Clojure (leiningen) for example uses a project file written in Clojure (S-expressions) for defining the project structure https://github.com/technomancy/leiningen/blob/stable/sample.project.clj.
We can even do better by incorporating F# type providers into the project definition process, for example to use a file type provider to get IntelliSense for file paths.
@Krzysztof-Cieslak https://github.com/Krzysztof-Cieslak has a blog post with some ideas of how a custom project file could look like "Creating custom project file for F#" http://kcieslak.io/Creating-custom-project-file-for-F in case someone missed it.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/visualfsharp/issues/1339#issuecomment-289389506, or mute the thread https://github.com/notifications/unsubscribe-auth/AADgNADYi-JIiorH4Y8miHVTnaaDwYJOks5rp3W0gaJpZM4JJuVb .
Yes tooling is a big concern! But I think it depends from where the project gets created.
If someone creates a project from Visual Studio then he expects good tooling for project files from the VS side. When creating a project from the command line msbuild is a hassle. Even with the new .NET Core .fsproj file.
Creating a (dynamic) .fsproj file from the DSL should be possible (so any msbuild-compatible system is able to compile the code). Updating the DSL file from the msbuild world is the hard part.
PS: this is my 10000 (or better 10_000 ;) ) foot view from an outsider not knowing very much of all the work behind getting F# to work with msbuild. I admire the work everyone from the F# community did to get F# to where it is today!
I think current project and build system is really huge problem for anyone trying out F# who was not C# dev before (https://www.reddit.com/r/programming/comments/61kt36/functional_programming_design_patterns_by_scott/dffbida/) - personally, I don't know anyone who was non .Net dev and understood MsBuild right away, and felt it was user friendly, easy to use etc.
The problem with custom project system is always tooling.
I'd argue about it. Most tooling shouldn't be problematic, anything that depends on FCS would support new project without any problem. I had proof of concept with Paket integrated into project system so dependencies management wouldn't be a problem. The only problem are XS and VS since they depend on understanding project files... and last time I've checked XS project system extension point was decent enough.
Also, I believe that it would be possible to add VS support too - R tools for VS, and Python tools for VS supports own project files by providing micro MsBuild-like file and resolving all information in memory. AFAIK, TypeScript does something similar but VS integration is not OSS.
Example rxproj
:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<ProjectGuid>8128d848-4b00-4036-8547-7344e5148a7d</ProjectGuid>
</PropertyGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
<Configuration Condition="'$(Configuration)' == ''">Debug</Configuration>
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
</PropertyGroup>
<ProjectExtensions>
<VisualStudio>
<UserProperties />
</VisualStudio>
</ProjectExtensions>
<Import Project="$(MSBuildUserExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\RTVS\Rules\rtvs.rules.props" Condition="Exists('$(MSBuildUserExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\RTVS\Rules\rtvs.rules.props')" />
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\RTVS\Rules\rtvs.rules.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\RTVS\Rules\rtvs.rules.props') And !Exists('$(MSBuildUserExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\RTVS\Rules\rtvs.rules.props')" />
<Import Project="Examples.InMemory.Targets" Condition="Exists('Examples.InMemory.Targets')" />
</Project>
Example rproj
:
Version: 1.0
RestoreWorkspace: Default
SaveWorkspace: Default
AlwaysSaveHistory: Default
EnableCodeIndexing: Yes
UseSpacesForTab: Yes
NumSpacesForTab: 2
Encoding: UTF-8
RnwWeave: Sweave
LaTeX: pdfLaTeX
Not only properties are resolved in-memory based on other project file, but also files which are displayed in project explorer are found automatically (which couldn't happen in case of F#, but at least shows that there are ways to hack into VS project system to support something better).
I had pretty decent proof-of-concept doing:
but since I'm not brave enough to annoy MSFT even more it's kinda stale.
On the other hand there are some drawbacks - MsBuild is SUPER complex. I mean, even MSFT failed to replace it with lot of resources put into it (project.json
fiasco). So it's pretty unrealistic to expect that any new project file will provide same functionalities natievly as MsBuild.
The assumption behind my proof of concept was to support most commonly used things (which covers majority of users) and then provide really good transformation into fsproj
- if someone wants more advanced features (let's say custom tasks, Xamarin magic etc) would have ability to move to full blown fsproj without any problem.
I like the idea of having a F# DSL (or data structure) to describe the project structure of an F# project.
Personally I don't like this idea - we change something that it's hard to parse, that only one tool is able to interpret well (MsBuild) into something that would be hard to parse and only one tool is able to interpret well (F# compiler). Also using TPs etc would mean that tooling is required to make changes in project file, which is not something I'd like to see. Paket proves how well simple, notepad-editable file formats work.
Instead I'd prefer highly declarative project file removing all "moving" parts (custom tasks, custom conditional syntax and variable assignment we have in MsBuild) in TOML or YAML that can be easily parsed using any TOML/YAML parser in any language.
FsToml sample:
FsTomlVersion = '0.0.1'
Name = 'FantasticApp'
Guid = 'bb0c6f01-5e57-4575-a498-5de850d9fa6c'
OutputType = 'Exe'
FSharpCore = '4.4.0.0'
Files = [
{ Compile = "src/file.fs" },
{ Compile = "src/file2.fs", Link = "src/uselessLink.fs" },
{ Compile = "src/file3.fs", Sig = "src/file3.fsi" },
{ None = "src/script.fsx", Private = true },
]
References = [
{ Framework = "System" },
{ Framework = "FSharp.Core" },
{ Project = "Deppy.fstoml" },
{ Library = "lib/Fable.Core.dll", Private = true },
{ Package = "Nett" }
]
DebugSymbols = true
DebugType = 'full'
Optimize = false
NoWarn = [52, 40]
OtherFlags = [ '--warnon:1182' ]
[ net ]
DebugSymbols = false
[ net.Release ]
Constants = [ 'RELEASE', 'FABLE' ]
DebugType = 'pdbonly'
Optimize = true
[ net."4_5".Release.x86 ]
OutputPath = "bin/Release/x86"
[ net."4_5".Release.x64 ]
OutputPath = "bin/Release/x64"
This is probably still too verbose and could be shrinked using good defaults.
Custom project, custom CLI tool, good migration path both ways and our live would be much better. Unfortunately looks like there is not enough interest in something like that to make it happen...
Also, to quote myself from this thread, couple of months ago: "Unfortunately this repository due to it's nature is probably worse place to discuss similar ideas, anyway ;)"
Edit: corrected typos.
We had a similar discussion earlier in this thread. I will repost a few relevant quotes at the end of this comment for convenience.
@Krzysztof-Cieslak
Indeed, that's the biggest problem. In current project file we have - project definition, dependencies, build configuration, sometimes build scripts, VS configuration. Also because we basically have embedded programming language in fsproj it's (almost) impossible to parse this file without using MsBuild (what is really annoying from tooling point of view... cough... tooling different than VS)
You hit it on the nail! I think it's always best to separate things that can be separated. Each of these concerns should be a separate file - each possibly consumed/produced by separate tools - and not all files necessarily have to - but could - share the same format. In any case, there should be at most 2 different languages: Static/simple/machine independent/configuration-like information should/could be in a dedicated configuration format like TOML (as opposed to textual data formats like XML, JSON, YAML, etc.) and dynamic/complex/machine dependent/reusable/moving parts must be in a statically typed DSL like F# (as opposed to the insane idea of misusing data formats for that like MSBuild, Ant, Maven).
The popular build scripts (MSBuild, Ant, Maven) are like CSS: It sucks so much that it makes me feel ashamed that it is still being used today by people who share the same profession. Then some people put an abstraction on top of it like LESS or SASS to make it suck less (comparable to tools that make MSBuild or C# suck less). The simplicity, restrictiveness and independence of dedicated configuration formats like TOML has obvious advantages, but a DSL - always being able to represent configuration information - can represent everything that a configuration format can. I am still undecided what would be the best exactly, but the following could be the basis for a separate discussion (@all: which repository would be the best place for that discussion, so that I or some one else could create an issue there for further discussion?):
concern | format | language |
---|---|---|
project definition | configuration format | TOML |
dependencies | configuration format | Paket "language" or TOML |
build configuration | configuration format | TOML |
IDE configuration | configuration format | TOML or whatever that IDE is using |
build script | simple declarative DSL | F# |
The information in all of these files could then be merged into MSBuild or other legacy formats for backwards-compatibility.
@toburger
I like the idea of having a F# DSL (or data structure) to describe the project structure of an F# project. Clojure (leiningen) for example uses a project file written in Clojure (S-expressions) for defining the project structure.
We can even do better by incorporating F# type providers into the project definition process, for example to use a file type provider to get IntelliSense for file paths.
This is why I am on the fence on this issue since I also like the idea of using F# type providers for checking the validity of files and dependencies before the build can even be run. I just don't know if the added complexity is worth it compared to a simple configuration format and checks performed by external tooling though. We need to weigh the pros/cons.
@Krzysztof-Cieslak
Personally I don't like this idea - we change something that it's hard to parse, that only one tool is able to interpret well (MsBuild) into something that would be hard to parse and only one tool is able to interpret well (F# compiler). Also using TPs etc would mean that tooling is required to make changes in project file, which is not something I'd like to see. Paket proves how well simple, notepad-editable file formats work.
Agreeing with you in principle, I just want to point out that requiring tooling like basic F# tools - that you use anyway - is not necessarily a bad thing. It's like using Notepad as your editor: While Notepad might be okay for simple dynamic languages (i.e. still not a good idea), you give up most of the benefits of having a (proper) statically typed language like F#.
@7sharp9
For me msbuild is the same as the WCF mess. There are far too many issues from using that format. There are just too many things trying to fit into the project file, which should just be a list of files and dependent project, which may or may not need to be built.
If you look at other languages and platforms theres no where near as much peril involved. Take cargo in rust as an example, its a joy to work with. Take hex from Elixir, again a joy.
@21c-HK (me)
Imagine being able to use type providers that check the validity of file paths and other dependencies before executing a faulty build script.
@21c-HK (me)
The problem is not that XML is a crappy textual data format, which it is (because it is neither human-readable nor optimized for being processed by a machine), but that developers keep misusing data formats for build scripts (e.g. MSBuild, Ant, Maven), weird declarative GUI specification languages with code integration where everything is expressed with string values (e.g. XAML with data bindings, events and animations), configuration files (e.g. Spring, Android App Manifest), databases and other mad ideas that should be expressed in a sufficiently expressive statically typed programming language that supports simple declarative DSLs (e.g. F#).
@Krzysztof-Cieslak
Custom project, custom CLI tool, good migration path both ways and our live would be much better. Unfortunately looks like there is not enough interest in something like that to make it happen...
Also, to quote myself from this thread, couple of months ago: "Unfortunately this repository due to it's nature is probably worse place to discuss similar ideas, anyway ;)"
I think there is a lot of interest for core issues like these even if it is not necessarily visible. Feedback/involvement like yours is much appreciated by passionate F# developers like me and raise awareness for issues that hold back F# adoption. And this is ultimately why I wanted to continue the discussion of F# adoption in this thread. I don't know if I can take even a little bit of credit for raising awareness, but since making the statement in the beginning of this thread that I thought that VS Code with ionide was better than Visual Studio with VFT for most projects, then some people disagreeing with my statement, and me then posting my wish list for an ideal F# IDE, VS Code with ionide has improved so much that it even supports most of my wish list, so that I am even more confident today to repeat that statement. The same might happen with the project/configuration/build system of F# if we keep raising awareness.
P.S.: Every F# developer should really check out VS Code with ionide again today! I can really recommend it for most F# projects. I would also like to give a huge thanks to Ionide maintainers like @cloudRoutine. Your effort is much appreciated and adds tremendous value to the F# community!
Each of these concerns should be a separate file - each possibly consumed/produced by separate tools - and not all files necessarily have to - but could - share the same format. ....
I think going to so many separate files is moving to another extreme. I think having project definition, and package definition in one file is OK... maybe even build configurations as long as it's static (i.e. doesn't contain custom programming language to manage like MsBuild with its conditionals and variable assignments). The biggest issue for me are dynamic parts of MsBuild - conditionals, variables, tasks. Conditionals and variables can be replaced with static declarative syntax (as vast majority of people always use same conditions, same targets etc). And for build script / tasks we have FAKE which is really good at what it does.
Anyway... we could just copy Rust's Cargo without thinking at all and situation would be better than what we have right now.
Feedback/involvement like yours is much appreciated by passionate F# developers like me and raise awareness for issues that hold back F# adoption.
Great that my feedback helps just a bit ;] Glad this discussion is moving forward and helping F# community!
Something something VSCode something
Nah, Ionide is not better than VS... One could argue about VS2015 without VFPT, but definitely not with VFPT, nor VS2017 Nightly build. But yeah, huge thanks to @cloudRoutine and other Ionide maintainers ;]
I don't really think that the .NET approach for projects and builds are hampering adoption much. It's an easy whipping boy which isn't the root of various issues with F#. The link @Krzysztof-Cieslak pulled up:
(a) Lacks the detail to be actionable (b) At face value, demonstrates a lack of comfort with compiled languages in general
If there's any truth to the latter, F# won't be picking up programmers from that camp.
I think that under the umbrella of getting started, F# has these problems:
It's a functional programming language. People learn Java, Python, C, and JS in school. The Java takeover of universities has been probably the most successful thing in the history of Java. We're still dealing with that today. Although universities are slowly standardizing their curricula to include compilers and functional programming, CS is still a young field in education and standards aren't widespread. This is the biggest hamper on adoption for F# moving forward.
No standardized CLI toolset for F# yet. Related problem: there's also no agreement on what "standardized CLI toolset for F#" means among the F# community. Multiple competing interests. The .NET CLI may eventually be the answer, but it's too young and hasn't even been pushed by Microsoft all that hard yet. I think it's better than anything which depends on Mono because Mono is too large.
No agreed-upon best library or framework for building a dead-easy web API or web page. Suave looks like it's the closest here, though. I think we're actually pretty close to having mindshare around Suave, and I've certainly been a part of that by suggesting it officially on Microsoft videos. I plan on doing more here.
Analogous to (3), No dead-simple way to start with iOS, Android, or Web frontend development. I think Xamarin tooling has come a long way and we're a few templates away from having roughly the same story as C#. VS for Mac is actually a great experience. FABLE looks to be the community-approved answer for web apps. I'm excited to see this flesh out more when 1.0 is stable.
No easy way to compile into a single, native binary. Though this isn't really about getting started, it's important. In the case of a language like Golang, it definitively answers the question of "what happens with I build a real application"? We're not really alone here. Any competing functional language on the JVM shares a similar problem.
In-box VS IDE experience lacks templates and is still catching up to C# in terms of IDE features. We're actually much further along now than ever, and the pace of IDE features in VS has been astounding. Don't be surprised if we're seen as leading in the IDE space pretty soon. We tend to underestimate the number of developers using Windows and Visual Studio. Let's not lose sight of the fact that this is a gargantuan population of people. Templates also matter a lot here, because wiring things up when a designer doesn't "natively" understand F# is not that nice. This isn't a very difficult problem to solve, which is good!
In-box VSCode experience is still complex. It pushes multiple F# OSS concepts on someone at once: FAKE and Paket. Though these are tools people should probably use, they're not ideal for someone who is just dipping their toes into F# and .NET. Paket will inevitably confuse people with the need to track stuff in multiple files, and it's easy to end up restoring packages without actually having the package installed so you can reference it. This isn't an Ionide problem, but it's one that Ionide inherits by virtue of using Paket.
Let's not let my above list discourage us, though.
The VS IDE experience is absolutely kickass with the nightlies and when we insert into a forthcoming update it will be impressive. I'm super excited about this.
VSCode is absolutely kickass. Nearly everyone, after they get over a bit of a concept hump, loves it. I demo it to people all the time.
.NET CLI "just works" for F#. FSI support here will complete the picture.
VS for Mac is fantastic. Some issues with completion, and I've run into a bug building an iOS app, but overall it's really amazing getting such a powerful IDE on the mac. This will attract people.
Suave is kickass. It has a very good "cool" factor that's nearly impossible to quantify, but somehow materializes.
FABLE is the kind of thing that makes peoples' eyes open wide. Really excited for 1.0 here.
The language is great. It looks good, people love using it, and it's stable (modulo bugs, which every compiler on earth has).
F# as a whole has a demonstrated "cool" factor that we've seen in user studies. Similar to Suave, we're not sure how, but it passes the "cool" test. ¯_(ツ)_/¯
F# is a natural attractor to people who use C#, love LINQ, and want more. Cannibalizing C# isn't the only way for F# to grow, but it's a natural one which attaches itself to growth vehicle. There's room for growing awareness in C# developers, keeping them happy on .NET because they get to use a cool language like F# on it. We shouldn't ignore this.
Almost every objective measure of growth we have shows F# as growing at least proportionally to that of C#. It's also getting good press through Redmonk, Infoworld, StackOverflow Surveys (yes, it dropped in some places from last year), and Microsoft itself. I just finished a video showing off VS IDE tools and building a dead simple suave app.
A lot of what I consider to be problem areas can't be fixed immediately. I think templates for VS and VS for Mac are an easy win, though. We lose out on C# developers trying out F# because all they see are Console Application and Class Library. I also think we should try to get a Suave template in there. I'll certainly approve the pull request and merge it into the repo.
I don't really think that the .NET approach for projects and builds are hampering adoption much. It's an easy whipping boy which isn't the root of various issues with F#.
I don't think I agree, given projects I'm working on I'm often contacted by people struggling with MsBuild. From my anecdotal experience getting started UX is pretty bad [unless someone is committed to MSFT tooling - VS / XS which for various reason is often a problem for people who don't have .Net background]). I've seen same reactions on various non-.Net conferences, or in my consulting work. Maybe I'm just unlucky and meet / talk / work with "wrong" people.
And yes, maybe dotnet
cli will make it better... maybe.
It's a functional programming language. People learn Java, Python, C, and JS in school. The Java takeover of universities has been probably the most successful thing in the history of Java. We're still dealing with that today. Although universities are slowly standardizing their curricula to include compilers and functional programming, CS is still a young field in education and standards aren't widespread. This is the biggest hamper on adoption for F# moving forward.
Yeah, in comparison to C#, JS, TS... doesn't explain why languages like Elixir are getting more popular / more hype faster than we're getting (obviously such comparison would be easier if you released those super secret usage numbers ;) ). And blaming something that we can't change is not productive anyway.
No standardized CLI toolset for F# yet. Related problem: there's also no agreement on what "standardized CLI toolset for F#" means among the F# community. Multiple competing interests. The .NET CLI may eventually be the answer, but it's too young and hasn't even been pushed by Microsoft all that hard yet. I think it's better than anything which depends on Mono because Mono is too large.
I don't think it will be solved with dotnet
cli... But anyway... again, due to the nature of this repository, dotnet
cli is official response for the problem ;)
3/4
I think we won't ever has one-go-to-choice for those problems due to Community vs MSFT dichotomy... and yes, You're doing great job promoting community based solutions, but Suave will never get as much marketing as ASP.Net, Fable will never get as much marketing as TypeScript and Xamarin... and I think at this point it's pretty clear which solutions are preferred by community ;)
In-box VSCode experience is still complex. It pushes multiple F# OSS concepts on someone at once: FAKE and Paket. Though these are tools people should probably use, they're not ideal for someone who is just dipping their toes into F# and .NET. Paket will inevitably confuse people with the need to track stuff in multiple files, and it's easy to end up restoring packages without actually having the package installed so you can reference it. This isn't an Ionide problem, but it's one that Ionide inherits by virtue of using Paket.
Wouldn't agree with FAKE - it's totally optional, one can use either VSCode tasks or set of MsBuild commands that Ionide provides out of the box.
Paket on the other hand - Ionide goes with it because out of the box .Net alternative is so bad that suggesting it to anyone should be felony. And which could be solved with better project file, that Paket can either be part of (merging paket.references and project file) or provide much easier integration path... Also, again, from my anecdotal experience Paket is not a problem, and is pretty easy for new people.
Templates
Obviously, more templates have no drawback.... other than
Almost every objective measure of growth we have shows F# as growing at least proportionally to that of C#.
Growth of absolute numbers of developers is nothing surprising given how crazy is growing number of developers jobs in general.... even super stagnant C# community is starting to notice that something is wrong (new "alt-.Net" etc)
Summing up, I think we have 2 different problems - adoption from C# -> F#, and adoption from outside of .Net world. And if most users of F# are VS, Windows, ex-C# devs that actually indicates huge problem that should be solved and (almost) no one is trying to solve. Which is super weird as I'd think that developers outside of .Net should be more important target for MSFT F# marketing (as those are new users for .Net platform, MSFT gains nothing when someone moves from C# to F#)
Fable kickass, Ionide kickass, Suave kickass....
I wonder how sustainable it is given that all those projects have 1-2 overproducing maintainers doing all work on their free time. Doesn't sound like a best strategy for developing ecosystem.
This is a minimal F# wrapper over asp.net core- https://github.com/dustinmoris/Giraffe
Not to beat a dead horse (again,) but F# being a second class citizen in VS releases definitely makes driving adoption much harder. Right now many people want to start using .NET Core (and the latest VS release of course.) That usually means folks will be creating new projects given that .NET Core and legacy .NET Framework projects don't play nice...and what better excuse to give people a reason to start using F# than greenfield projects?
VS Code is nice and all, but it's not Visual Studio.
Thankfully its not Visual Studio.
We have a whole cornucopia of option, vscode, sublime, emacs, visual studio, and xamarin studio. Lets not get sidetracked by a development environment choice, F# is not a windows only product.
@7sharp9 I absolutely agree that F# is not a Windows-only product and for non-Windows users, they can absolutely use VS for Mac/VSCode/etc and if part of the goal is to drive adoption significantly higher, targeting the large number of existing developers who already invested in VS / .NET might be give us the biggest bang for our buck.
People are complaining about .fsproj files/msbuild on conferences: https://youtu.be/JgWQPPnKWZU?t=10m23s. I don't think it is that bad of a situation to decide against F#, but I can understand his complaints.
@cartermp I'm probably in the minority, but the old .fsproj
file was a big impediment to me. I'm on Linux, and I'm not using VS or VSCode, so I have to hand-edit the .fsproj
file.
I don't like clicking buttons in fancy IDEs either, I prefer to actually understand how the files work. And the documentation I found for .fsproj
is atrociously bad, probably because it's assumed that everybody is using VS/VSCode.
Popular and hip languages (such as JavaScript, Ruby, and Python) have nice, simple, easy-to-understand, and easy-to-edit configuration files. Even static languages like Rust and Haskell have better configuration than F#. This is a big win for people who are new to your language.
The new .fsproj
file is great though, and I think it will help with adoption.
I'm sure the rest of your points are also big problems (which should definitely be dealt with), I just disagree that the old .fsproj
wasn't a problem.
@toburger @Pauan To be clear: I'm not saying that .fsproj
isn't an issue. I'm saying that in terms of adoption, I don't think that it's a big factor. That's a downlevel concern. I'm not particularly concerned about that, especially since there's already a clear path forward with MSBuild 15-based project files. I'm interested in the answers to questions which come before someone is concerned with day-to-day work in project configuration.
There isn't what I would consider to be very strong mindshare around things like building a simple web service, for example, which is increasingly becoming the "hello world" in many circles. I think we're making huge improvements, here, though. F# Software Foundation is also growing, as is activity in the FSSF slack, where things like Ionide + Suave are recommended for folks not interested in an IDE. This is something to build off of.
@Krzysztof-Cieslak
Yeah, in comparison to C#, JS, TS... doesn't explain why languages like Elixir are getting more popular / more hype faster than we're getting (obviously such comparison would be easier if you released those super secret usage numbers ;) ). And blaming something that we can't change is not productive anyway.
Hype doesn't necessarily translate to active developers. Neither does Google trends. Languages with an affinity to one set of systems may be completely irrelevant in other markets where another language has affinity. This doesn't mean some other language is doing better or worse, for some definition of better or worse, than F#. I think we're all competing over roughly the same (small) order of magnitude of developers, save for Scala, which has been successful largely because Java became absolutely stagnant for half a decade.
I'm not blaming education. I'm simply stating a reality: the biggest problem with adoption for F# is that it's a functional programming language, and functional programming languages are not taught in school. I say this because perspective matters here. School is where the largest group of soon-to-be paid professionals, open source developers, and thought leaders come from. The funnel for F# adoption, as with other FP languages, does not have a high amount of students in it. That's the largest hamper on adoption bar-none. Perhaps the greater FP community ought to take this more seriously. We're tied to it.
Also, again, from my anecdotal experience Paket is not a problem, and is pretty easy for new people.
I've also seen precisely the opposite experience: people doing just fine with dotnet restore
in the C# extension, but struggling with Paket. But this isn't a conversation about package managers. Package managers seem to come with strong opinions. ¯\(ツ)/¯. My point is that there's extra conceptual stuff which comes with a basic Ionide project. This may not be actionable, especially since you can ignore most files and just write some code.
I'd think that developers outside of .Net should be more important target for MSFT F# marketing (as those are new users for .Net platform, MSFT gains nothing when someone moves from C# to F#)
This is actually not true at all. Microsoft has a lot to gain when someone moves from C# to F#. It's usually a strong sign of satisfaction and happiness, and is associated that way. Keeping people happy (or stopping the bleeding, depending on your point of view) is crucial to Microsoft business interests.
This is both a blessing and a curse for F#. Appealing to existing .NET developers and non-.NET developers necessitates a breadth of tools and a simple grow-up story across the spectrum of tooling people prefer. That's a bunch of words which means: quantity and quality matter. We're very much on our way there, especially as .NET Core and its associated tooling is materializing into something stable which runs everywhere. Unsurprisingly, much of what the existing .NET community had been asking for (compat with existing code, better project files, larger API set with no breaking changes) aligns with what non-.NET developers care about as well.
I've also seen precisely the opposite experience: people doing just fine with dotnet restore in the C# extension, but struggling with Paket.
Probably Microsoft employees. It's 2017 and they still use "restore" for a resolution call ;-) (and it's really weird since you use exactly the same dotnet restore to do a actual "restore" in paket.)
@cartermp honestly. Look at cargo. Look how really good project file + package manager integration works. "paket will confuse people that just come to .NET " - that's really really bad thinking especially since most other platforms have a package manager that works similarly. Nuget is the odd thing. It really is. Having still no lock file is what people let themselves shoot in the foot. I never claimed paket should be the package manager that comes ootb, but I really really hoped ms would finally understand the danger it brings with nuget. But instead it's switching product managers every year and so noone can make an impact. I admit that the PackageReferences stuff made things much easier to get started but boy that stuff will make builds break A LOT. If you don't believe me than work a while with npm and after many many tears you will understand why yarn was made. Tbf one advantage of yarn is that it is a drop in replacement. We couldn't do that with packages.config for very good reasons - we might converge now.
@forki I enjoyed FAKE and understood the value of Paket, but overall VS packaging solution became easier (less boilerplate and additional dependencies and mental overhead) since project.json, and since VS2017 it is kind of joy (relative to all the pain before with .NET Core, now references to/from Core and NET45 projects "just work"). And NuGet started to work as it always should have been - fast and without version resolution problems. This all applies to F# as well - I could create a .NET45 F# project in VS2017 and have all the tooling, but a separate .fsproj
file in .NET Core format and a build script that builds & packs projects using dotnet
cli. Support for .NET Core F# projects from VS2017 is the last step to have a truly awesome tooling/build/packaging infrastructure out of the box.
Coming back to the original topic. MSBuild (even 15 and PackageReferences) is a real problem for adoption. If discuss this away then you obviously never spend time in the fable gitter chat. A lot of the people come from Javascript ecosystem. They are not scared by F# or functional programming because we mainly show super simple + super effective elmish architecture. But they are indeed scared by our project files. That's a real problem compared to let's say elm itself. We also don't hear much complaints about package managers, that are not npm.
without version resolution problems.
No it doesn't. You just not noticed it yet.
People going from Ruby to Elixir are not scared of FP, people going from JS to Elm are not scared of FP. Personally I believe that "blaming FP" is just excuse... and what's more important, many other communities stopped using it, and instead they are doing right things to make developers live easier.
For last 5 years it was "Nuget is OK because it's better than old dll hell" . Now it is "dotnet restore
is OK because it's better then old NuGet" and "new fsproj is better than old fsproj". All those statements are true... they're just missing part where you mention that we compare terrible thing with slightly less terrible thing. While (most) other ecosystems already solved this problem much better.
IF we agree with this dominating here "Yeah F# is xplat, people can use those wierd hippy things like VSCode but Windows and VS are what really matters" view of the F# world than yes, be happy with new fsproj, Nuget and dotnet cli. And telling that stats show vast majority of F# devs are Windows, VS, ex-C# devs is not proving this world view. It's just another symptom showing what's wrong with our ecosystem. But I guess we should be happy with being MSFT dependent poor cousin of C#.
Anyway, I guess due to different experinaces and point of views on the issues we should agree to disagree ¯\(ツ)/¯
The last few posts (especially by @forki and @Krzysztof-Cieslak) is exactly why this thread/discussion is so important. Microsoft employees may have a certain view of the state of things - and while the participants in this thread may not be representative of the F# community at large - the disagreement in the last few posts shows that the F# OSS may have a different view of the state of things. Neither is necessarily right or wrong, but it's valuable to find out where the issues/truth may lie.
@cartermp
I don't really think that the .NET approach for projects and builds are hampering adoption much. It's an easy whipping boy which isn't the root of various issues with F#.
I also have to disagree with that statement. Maybe "adoption" means something else to you, but for me adoption means that people try a technology and then decide to stick with it. I was literally forced to switch from NuGet to Paket, because the "stable" NuGet was so incredibly buggy and no amount of updates over a time span of a year did improve it. From the second that I learned Paket and switched to Paket, I had no problems ever again! Microsoft's problem has always been "Check out this 5 min demo video. Isn't cool how quickly you can solve this particular (staged) problem with our solution (that is only really good for that particular problem)?" And then you try something else, more complex, or more general with that technology and you start pulling your hairs out. C# async, ASP.NET, WCF, WPF, XAML, WinRT, MSBuild and NuGet are just a few examples from the top of my head.
@cartermp
- In-box VSCode experience is still complex. It pushes multiple F# OSS concepts on someone at once: FAKE and Paket.
I really don't understand this statement. These are not F# OSS concepts, but fundamental concepts of software development called "build tool" and "dependency manager" that any professional developer should be familiar with before even starting a project. The only difference between FAKE and MSBuild, or Paket and NuGet, is that FAKE and Paket actually work every time that I used it (so that I can focus on programming) and MSBuild and NuGet make me lose respect for Microsoft every time I use it. It's actually just bad marketing for Microsoft, because a lot of other things that Microsoft does are really great (e.g. F#, .NET, VS editions, etc.).
@Krzysztof-Cieslak I agree with that we seem to content ourselves with incremental improvements to a crappy set of existing conditions (let's not sugar-coat it, csproj/fsproj/NuGet suck.) Incremental improvements will not move the adoption needle.
"Yeah F# is xplat, people can use those wierd hippy things like VSCode but Windows and VS are what really matters"
I don't think that's meant to slight non-Windows / VS users (or potential users.) Existing VS users simply provide a lower barrier to adoption than say your typical non-Windows developer who at minimum is suspicious of using anything from the "evil Microsoft empire." Furthermore, the impression is (like it or not) that F# is not a first-class citizen in the VS/.NET world. Unless Microsoft corrects that idea, they won't even get existing .NET developers onboard with F#. I can't even create an ASP.NET Core F# project in VS2017 (even with the full .NET Framework.) How pathetic is that?
Regarding the project/build system, I need to quote myself to re-establish the context:
@21c-HK (me)
Each of these concerns should be a separate file - each possibly consumed/produced by separate tools - and not all files necessarily have to - but could - share the same format. ....
I am still undecided what would be the best exactly, but the following could be the basis for a separate discussion ...
concern format language project definition configuration format TOML dependencies configuration format Paket "language" or TOML build configuration configuration format TOML IDE configuration configuration format TOML or whatever that IDE is using build script simple declarative DSL F#
@Krzysztof-Cieslak
I think going to so many separate files is moving to another extreme. I think having project definition, and package definition in one file is OK... maybe even build configurations as long as it's static (i.e. doesn't contain custom programming language to manage like MsBuild with its conditionals and variable assignments). The biggest issue for me are dynamic parts of MsBuild - conditionals, variables, tasks. Conditionals and variables can be replaced with static declarative syntax (as vast majority of people always use same conditions, same targets etc). And for build script / tasks we have FAKE which is really good at what it does.
As I said, I was still undecided and I agree with you in principle. I just wanted to list the concerns and map each concern to the preferred format/language as a basis for discussion. We can see that project definition, dependencies and build configuration could use the same format (= TOML), so it might make sense to put them in a single file for convenience. But I don't think the number of files is the real issue here, but rather different formats/concepts. I don't really care if these 3 concerns are in the same file or in 3 files in the same folder as long as they are using a single easy-to-understand format. The only difference is that I don't have to hunt for the section in a single file that represents a concern compared to separate files and that different tools don't run into each other when working on the same file with different concerns.
I also tried to keep the table as general as possible. I was implicitly referring to FAKE when I said "simple declarative DLS in F#" and we already have it. We also have a great dependency manager (= Paket). While it does not use TOML (support could be added though), we already have it and it works really well. So we have everything except a a good open source cross-platform project system for F#.
I would like to continue the discussion on the project/build system in a separate dedicated thread. Do you have suggestions which repository would be the best for that?
@Krzysztof-Cieslak
I wonder how sustainable it is given that all those projects have 1-2 overproducing maintainers ...
I'm coming around to that the best approach to this is to encourage the maintainers to recruit at least 1-4 other maintainers. And to encourage all users to become contributors. There are many structural things we can do as a community to help each other achieve this. Sharing best practice around CI, docs, API key management, simplifying base tooling, avoiding churn in base tooling and so on.
Open source is very, very productive. All great open source tooling has 1-5 key developers at its core. Having 1 key maintainer is indeed tricky. Having 3-5 is much more solid. It's hard though, I know, and even with 3-5 people come and go. (Commercial projects suffer from the same phenomenon, just worse, because you have to recruit both significant $$ and managerial support for the entire lifetime of the tool.)
In any case it's something we should definitely talk about regularly, and be open and honest about. I like to think of "health assessments" for OSS projects - one aspect of which would be "how many maintainers do you have?"
@Krzysztof-Cieslak wrote:
For last 5 years it was "Nuget is OK because it's better than old dll hell" ...
There is at least one senior developer among my colleagues who would disagree. We have a lot of internal libraries that several of our software products use -- and our build scripts are currently set up so that if product A uses library B, it downloads libB.dll
from the relevant build artifacts on our TeamCity server. I am NOT making this up. I recently brought up "Why aren't we creating NuGet packages for this?" and one of our senior developers said, "We tried that earlier, but it gave us no benefit, so we went back to downloading the DLL build artifacts from TeamCity."
In other words, he found DLL hell to be easier to deal with than NuGet. Let that one sink in for a while.
I had been planning to introduce Paket and say "Hey, this is better than NuGet, we should switch to it." But because my colleagues have an anti-NuGet prejudice based on previous bad experience, I'm going to have an uphill battle even getting them to try Paket.
Having good tooling really, REALLY matters.
@rmunn manual dependency management is a very sane approach. Especially for smaller solutions (with not too many external deps and only a handful of projects) it's basically ideal. I'm not joking here. For bigger solutions it can become really hard to keep track of everything, so a package manager usually helps. If you are in situation with hundreds of projects and many many deps then it's basically the only way to stay sane. Unfortunately nuget does not maintain anything across projects, so many people just don't think package managers are any good.
@Krzysztof-Cieslak
Anyway, I guess due to different experinaces and point of views on the issues we should agree to disagree ¯(ツ)/¯
Why? Having different anecdotal experiences shouldn't discourage you from engaging further. This just means that both of us have more to learn.
@forki
Probably Microsoft employees.
Nope.
We couldn't do that with packages.config for very good reasons - we might converge now.
It sounds like you're saying that you could be a drop-in replacement for NuGet w.r.t. PackageReference
? If so, that's great. Precisely the sort of thing that ought to happen.
@21c-HK
I would like to continue the discussion on the project/build system in a separate dedicated thread. Do you have suggestions which repository would be the best for that?
Good idea. Not sure where, TBH. dotnet/sdk
and dotnet/roslyn-project-system
are the most actionable places. The former is defining what the .NET Core SDK looks like and how that surfaces in projects. The latter is where the future F# project system will live (yes, we're replacing the current one with CPS and making MSBuild 15.0-based .fsproj
s the default for all things F# 😄). There may be good feedback to contribute about keeping project files as small as possible. @enricosada has also created the .NET CLI templates for F# using the new templating engine. It's very easy to create new templates now.
In terms of having an outright replacement for MSBuild and its associated file format, I don't think such a thing will be possible. There are so many little things it does that people rely on. Project.json was a two-year effort to rewrite this and they still fell well short of their goal. There were absolutely flaws in their approach, but I'm willing to bet my life savings that any effort to create a new project format and project system for F# which can talk to existing F# code will go down the same path project.json did.
I think the most productive thing we can do in this area is to champion a build DSL as the default tooling experience all-up. I've made the case for this internally before, but in the midst of trying to ship something for .NET Core it wasn't really considered. Once .NET Core gets to a usable state for most .NET developers alongside matured tooling, folks in those areas may be more open to this idea. CAKE and FAKE are the two obvious choices. Perhaps there are others, but creating an extensibility point within VS to allow you to use your build DSL of choice likely isn't much work. And the non-VS use case is already solved.
It sounds like you're saying that you could be a drop-in replacement for NuGet w.r.t. PackageReference
There is a subset of paket.references features that would work with PackageReferences in fsproj. Yes. But I'm not 100% sure it's a good idea.
my feedback, doing a lot of fsprj stuff.
the dotnet restore
(who is just nuget as msbuild task, in fact is dotnet msbuild /t:Restore
) and PackageReference
doesnt fix the old issues of nuget (lock file for app, deps version ranges for libraries), neither does the transitive dependencies.
these just hide the problem, with a less verbose and easy to use sintax.
A PackageReference
is just the old package.config
, just inside fsproj, so can also be read later by dotnet pack
(that's nice)
the new fsproj. If people continue to treat fsproj/csproj as project file definition, that's the first and big error. msbuild project are not project definitions (compile items, references, fsc arguments, etc). msbuild project are MAKEFILE. What ide does, is to evaluate that makefile, to gather the compiler args and other properties (common arguments, the files like Content who are not needed for compilation, but included in project, etc) That said, the msbuild project can be implemented with:
new fsproj/csproj is a big makefile, pluggable from new target/props from nuget packages. that's the real deal ihmo of new fsproj.
Now, using makefiles instead of (dumb project definition + runner) has props and cons. Is a choice.
that said, if you prefer a dumb project definition, and want to write your files list/props/deps as .json/toml , just generated a .props
file in obj/myproj.fsproj.example.props
, with all the info.
because exists this extension point, you can (that's what nuget does btw).
Or you can reimplement your makefile logic as F# script, is the same, is just a different language, with different sintax/rules/extensbility. I like xml? nope, but neither makefile sintax. f# is better as dsl for makefiles? maybe, but you need to implement some features as lib (incremental/deps order) and can be ok too.
Issue of VS and msbuild ihmo is it does try to cleanly separate and abstract the (msbuild makefile -> useful info) and command, but like that is easier to implement (for VS, because zero abstraction)
About paket, everything it does can be integrated cleanly in the new sdk (github files? -> Compile items auto included), etc. And is not a matter of xml vs F#, is just a matter of how and where extend an existing codebase (restore/pack). If that is written in xml+c#, or f# doesnt matter, these are just a flow of methods invocation, like every program.
Obv as F# and C# dev i prefer that sintax for set variabile, string manipulation, object creation, method invocation. but msbuild format is just another language. should we need to learn two language (F# and msbuild) to really change a build orchestration? that;s another question
If that is written in xml+c#, or f# doesnt matter
but msbuild format is just another language.
Well, everything is just a language. But languages do matter! Otherwise we would still be programming in assembly, which is also "just a language". MSBuild sucks. It has always sucked. Granted, it's old and back in the day when every one was insane thought XML was the solution for everything, lots of dumb things were developed that were based on XML. But it's 2017, we should learn from past mistakes. Anyone working for Microsoft or another company that suggests today to create a build DSL in XML should be fired instantly due to (obvious) mental illness. And if you wouldn't recreate it, then why would you keep maintaining it?
It may be the case that VS just needs to use MSBuild because VS is so complex that it cannot be replaced in a reasonable amount of time, but that should not prevent other IDEs and build tools from using a shared project system for F# that does not suck. May be the most reasonable solution is to have 2 project systems. MSBuild/CPS used by VS (because of backwards-compatibility and Microsoft's love of artificial complexity) and one used by all other tools (where its developers and users respect themselves). The intersection of the sets of users using both MSBuild/VS and another build tool for the same project is probably pretty small anyway.
Unfortunately nowadays, we build these things in json - which is about as bad as XML.
S-expressions are the way to go. Fortunately, there is an F# library that uses s-exprs for serialization, DSLs, and even a pluggable dynamic scripting language - https://www.nuget.org/packages/Prime/
😀
Unfortunately nowadays, we build these things in json - which is about as bad as XML.
Completely agree.
S-expressions are the way to go.
S-expression are even worse than JSON or XML, because it has less structure and even less type information than either. Structured data types like record types and union types in F# that can be checked statically is the best you could possibly hope for with regards to typed data, but TOML is fine for simple configuration information.
@21c-HK Just to offer a bit more historical context:
project.json was an ultimately failed effort to replace MSBuild. This was driven fundamentally by the fact that it could not talk to existing code in VS. That's a problem when the corpus of code is written in VS. That said, it brought certain capabilities to the table which have since been adopted by MSBuild, including:
The focus in the recent past has been to bring those capabilities (and more) to MSBuild, without sacrificing the ability to talk to existing code or tools. That work isn't 100% finished yet, as it also depends on platform changes for .NET Core. I should underscore this, though:
This doesn't mean MSBuild and MSBuild XML is the only thing people at Microsoft care about.
Right now the top-of-mind concern is how to get the gargantuan population of existing developers able to write code on .NET Core, .NET Standard, and Xamarin without having those projects live in silos. This affects F# as well. Once this is achieved, other ideas will be explored. I come back to the idea of championing a build DSL like FAKE or CAKE. This is a solution other platforms have done as well, and it's far more realistic than creating one's own build and project system.
I should be clear about my opinions regarding a new build and/or project system. Such an effort will be:
As with any inherently difficult domain, it's easy enough to get a basic proof-of-concept working. But when someone has a requirement such as generating satellite assemblies based on locale, it becomes a different story altogether.
It is factually incorrect to say that s-exprs have less type information than XML. Json may have additional literal types, but s-expressions have quotations - so that too is mostly false. The advantages of s-expressions are structural - try writing a scripting language with json syntax - you really can't hope to. You can sort of do it in XML (ugh), but then you lose the types offered by Json and s-exprs.
On Tue, Mar 28, 2017 at 1:17 PM, 21c-HK notifications@github.com wrote:
Unfortunately nowadays, we build these things in json - which is about as bad as XML.
Completely agree.
S-expressions are the way to go.
S-expression are even worse than JSON or XML, because it has less structure and even less type information than either. Structured data types like record types and union types in F# that can be checked statically is the best you could possibly hope for with regards to typed data, but TOML is fine for simple configuration information.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/Microsoft/visualfsharp/issues/1339#issuecomment-289841022, or mute the thread https://github.com/notifications/unsubscribe-auth/ABjN2Oa8JhRHSH_AYewmOMXSvUoU0jxnks5rqUC9gaJpZM4JJuVb .
It is factually incorrect to say that s-exprs have less type information the XML.
I meant type information as in product types (record or tuple in F#) and sum types (i.e. union in F#). XML has both even if I don't remember from the top of my head whether XML supports full blown unions or just enums as in C#. S-expressions by themselves have no explicit type information other than the basic type literals and the list structure. All structured type information is implicit.
Don't get me wrong, I would actually prefer S-expressions over JSON and XML, but not because the latter can encode a little bit of type information.
I see barriers to adoption as resistance on multiple levels. Every developer has an individual resistance threshold (or "pain"-threshold). If the technology directly or indirectly puts up enough resistance to overcome the threshold of that particular developer, then you have lost the interest of that developer - often times for good. This happened to me with Haskell's tooling on Windows when I tried it a few years ago. I've seen non-Windows developers optimistically try Mono to finally develop with .NET only to find out that it was too buggy (this was also a few years back).
Experienced developers have gotten used to so much bullshit over time (read "bullshit" as: stuff not working due to really silly reasons, or fighting unnecessary complexity) that they have developed a very large threshold for resistance they can put up with out of necessity. These experienced developers are willing to do almost anything to get something to work whereas beginning developers simply switch to a technology with less resistance ("where the grass seems greener"). As they get more experienced, they also tolerate more bullshit. This is why Javascript, Java and C# have become so popular. They have a low perceived resistance - whether superficial or not does not matter - because the barriers to entry are so low, i.e. very few simple concepts - like assignment and loops (and ignoring classes, initially) - is all you need to get started while amazing tooling hides most of the artificial complexity that will bite you in the ass when the code base grows. Just download VS, create new project, copy/paste code off the internet, run. Congratulations, you are a programmer 💪. Bang your head on the keyboard, install Resharper, let Resharper do its thing, and congratulations, you are an above-average programmer.
I am not necessarily saying that it should be like this, but Microsoft has always appealed to these developers. You don't need to know much, but still get something done. And then you can grow from there. This is why I got started with Microsoft technologies. They made VB 6 with VS 6.0 so easy that even a kid could get started and have stuff moving on the screen within a few minutes. VB 6 was so far ahead of C++ in terms of productivity and easy-of-use that it was proudly marketed as "rapid application development (RAD)" when that was a thing 😄. VB.NET and C# with VS.NET was actually a step back in that regard and I remember how people complained how difficult it was to switch from VB to VB.NET. There was already so much resistance that most VB developers switched straight to C#. I did too. The syntax was the smallest problem, but after switching to C# you could at least call yourself a "real" developer (VB developers were looked down upon) 😄.
A long time passed and since learning and using F# (and learning about other reasonable languages and technologies), my personal threshold for resistance has actually decreased significantly. I expect things to be simple and work out of the box, because I am not longer willing to waste my time on crappy technologies. In a sense, the F# language is the first technology that I tried that feels "RAD" again for developing large programs. I am looking forward for F# tooling to be "RAD" as well.
I've re-read the entire thread to see if there are common themes with regards to resistance. It seems to there are three levels:
Ideological resistance: "F# was made by Microsoft. I believe that Microsoft is evil. Therefore, I use an independent language". I think that is a very small (and very loud) set of developers that may never consider F# as a viable choice, or it's just a matter of time until these people realize that this is not true and that F# is actually in an ideal position: great open source community and steering and support from a company with immense resources that work together to create the best possible development experience.
Theoretical resistance: "F# does not have higher-kinded types. Therefore, it must be a toy language. I'll check out Haskell or Scala instead." - This is also a small (but loud) set of developers that may never consider F# as an alternative unless some really cool F# libraries get their attention and may convince them to at least try F# in practice.
Practical resistance:
The is the largest (and mostly silent) set of developers, which may get turned off by too much practical resistance. These developers usually just try to solve the problem and you may never hear from them ever again (whether they stick with F# or not). Removing practical resistance has the most impact on adoption (as Elm proves). And this is why I believe that a simple shared open source F# project system is so important. Combine that with VSCode, ionide, Paket, FAKE and a bit more sugar for a hopefully frictionless out-of-box experience in the future and we may have removed a lot of practical resistance.
A long time passed and since learning and using F# (and learning about other reasonable languages and technologies), my personal threshold for resistance has actually decreased significantly. I expect things to be simple and work out of the box, because I am not longer willing to waste my time on crappy technologies.
The core reason I'm interesting in learning and using F# is the promise of simplicity and increased productivity. I've been a .NET developer since v1.0 beta (when I had just graduated from university.) As much as I prefer C# over other C-family languages, I'm sick of all the boilerplate I have to write, and I've become weary of OOP - it's too complex to design a flexible, well-thought out system for line of business applications (for proof, go read Bertrand Mayer's Object-Oriented Construction (1296 pages!) I've been influenced by Rich Hickey's "Simple Made Easy" presentation (I'm sure most will be familiar with it.) After taking some time to learn React & Angular 2, I think I've reached my bullshit threshold and I'm not willing to take it anymore. I feel that application development (the process and tooling) has become overly complex without yielding substantive gains for the end users (that's why we're here right?)
What's holding me up personally with F# is practical resistance. I can't use F# with ASP.NET Core (well I can but are the project templates even up to date?) I can't use Visual Studio because of the missing msbuild 15 support, etc. Can I use VS Code? Of course, but I'm not a big fan of its UI/UX and ever little bit of practical resistance builds up and makes me doubt whether I'm making the right choice. I could fire up IntelliJ and start being productive in a number of languages where there's little practical resistance compared to these issues. The main downside for me would be leaving the .NET ecosystem. To be clear I'm not one of those developers who only knows a single stack (I've done Java, NodeJS, some Golang, Swift.), but for me, .NET is "home."
I hope folks don't take the above as just idle complaining - I'm optimistic about F#. I suppose I'm just being impatient ;)
@21c-HK Thank you for such an excellent and well-thought out summary post.
I'd add at least one other kind of resistance: loosely cultural resistance or network resistance: "I want to use F#, and there are no ideological, theoretical or practical reasons not to do it, and lots of reasons why it's a good idea, but the weight of my social/work/professional/economic/... network around me makes that difficult (for all sorts of reasons)"
You can just view this as the sum of the other three kinds of resistances across the social situation (work etc) you happen to find yourself writing code in. If you're writing code by yourself, that sum is zero. If you're in a massive corporation that only allows Java, then the sum is basically infinite :)
This kind of resistance is faced by nearly all technologies and is fundamentally different to the other categories. It is particularly strong when developers are faced by fierce managers who demand that a team stick to some particular language (and have probably already seen off numerous "young turks" who want to change things). It is also a factor when faced with teams that churn, or a corporate culture that only allows particular languages to be used, or a corporate culture that sees developers as interchangeable, or a corporate culture that basically wants to stop developers actually writing code (yes, it happens).
F# faces plenty of this kind resistance (though n some other ways less than other languages, e.g. it is at .NET language which can reduce overall cultural/network resistance compared to a native language)
This kind of resistance is odd: decreasing resistance along some other dimensions (e.g. adding lots of cool new technical features to decrease technical resistance) can increase resistance along this dimension (e.g. your boss is not deeply technical and hates you talking about these language features he/she doesn't understand). This is one reason why piling on new technical features is not necessarily a solution to decreasing resistance.
In the US, and likely other Western countries, we have a serious problem of capital allocation. For example, the way that capital is allocated in the US tends to be way overly conservative. Nowadays, capital only tends to flow from a vanishingly small set of overly risk-averse actors, acting either purely for the motive of lottery-level profit, or straight up politics. Give how locked up the US economy has been for the last decade or so, capital tends to flow only on a 'viral' basis - that is, unless your start-up has a one-in-a-million appeal, you won't hope to see a dime. In too many cases, the only way in which investors see themselves making money is by getting OTHER investors to put money into a start-up until valuations explode and the whole thing gets sold to a greater fool (EG - the investing public). I guess you could call this a 'hot-potato start-up phenomenon,' and it is a truly suffocating environment for small businesses that actually want to produce something of value for the consuming public.
Don mentions - with 100% accuracy - that what much accounts for our present technological inertia is cultural resistance. Ideally, functioning market have a great way to overcome this. In a functioning market, new businesses pop up all the time due to capital flows that arrive as an outcome of reasonable risk appetite. With new businesses come new ways of thinking, and adoptions of new technology exactly like ours. Unfortunately, as I explained above, we do not have a functioning market like in the US, nor in much of the West. And this is a huge problem for meritorious technologies like F#.
Now, as a conservative / libertarian I have some opinions as what can be done to unlock the US economy. But I don't have any reason to state them here because, frankly, I don't think anyone here has sufficient influence to affect any of the changes that are needed. This is macro-level stuff.
So let's instead talk about what we, as individual contributors and open source engineers, can do.
We have to understand that, in all but the most pathological cases, even locked up markets do eventually resolve issues. While an unlocked market might adopt new technology in a year or two, our locked up market often takes 5-10. That's just how it is in this type of economy - everything is in slow motion - including technology adoption.
For us, then, it must all be about keeping a stubborn long view and continuing to invest ourselves in to what we know is the right thing. It takes a lot of faith and grit to work for a future that is years away - but that's the nature of our economy's timeline, AFAIK.
BTW - I turned the above comment into a full-blown article here - https://medium.com/@bryanedds/how-locked-up-economies-put-the-adoption-of-programming-technologies-into-slow-motion-b8c2da89b93e
@dsyme Thank you for the (most) important addition with regards to kinds of resistance. You explained it better than I could have anyway. Of course, cultural resistance is the resistance with the most impact and it is also the most difficult to tackle due to its complexity and (sometimes unintuitive) interactions. Changing culture is always very hard (if not impossible).
One (for me at least) unexpected cultural factor was what Eric Sink refers to as "pragmatists in pain", which are a subset of mainstream programmers with enough pain to be willing to leave the safety of the herd (great article, btw)
Sometimes a pragmatist can be convinced to break with the herd. The key is to find what Moore calls a "pragmatist in pain".
A pragmatist in pain is someone whose needs are not being well met by whatever technology is current popular among pragmatists. The current technology is not merely annoying them. It is failing them.
A pragmatist in pain actually does care about how F# is better, even though this goes against their nature. They really hate the idea of listening to some F# nerd prattle on about immutability and type inference. But they have reached their last resort. Their pain has forced them to look for hope from somebody outside the herd.
This is how a new product gets across the chasm. Find a pragmatist in pain. Do whatever-it-takes to make them happy with your product. Then go back and do it again. Repeat until you have enough customers that they can go to PragmatiCon without being shunned and ridiculed. [...] I also understand that F#'s awesomeness is basically irrelevant to the question of whether it will go mainstream or not. If the pragmatists are not in pain, they are not interested. C# doesn't cause very much pain.
In other words, the chance of a new programming language becoming mainstream seems to be proportional to how much pain the old language is causing in the same ecosystem.
All these new languages improve upon (old) painful languages in the same ecosystem. The old languages were causing so much pain that switching to the new language seems to be worth it. But F# competes with C# on .NET - and C# is one of the best imperative OO languages that kept picking up all the features that were hyped over the years. Scala is basically C# with the addition of case classes, higher-kinded types, traits, implicits and different but kind-of-familiar syntax (Note: please don't derail this thread into a discussion on which programming language is better, this is not about that). Ignoring particular language features, Scala, C# and F# are all competing in the big league and even compete outside of their respective ecosystems. The perceived difference between C# and F# in terms of features is not that large. The first time I heard about F# I thought "F# is like C# with just a bit more emphasis on FP and weird syntax. Microsoft is still using C# to write all of its APIs. I can do everything in C#. All .NET tools are optimized for C#. Almost all .NET jobs are for C# developers. Why should I even consider trying F# if it's out-of-box experience is not like that of C#?"
Later I realized that C# is still causing way too much pain (of course, less than older languages, but comparable to the difference between the old language and new the language, and C# and F#, respectively). It's just not easy to see how much pain C# (and languages with similar problems) are causing when your bullshit threshold is approaching infinity. The beauty of F# as a programming language though is that its sum is greater than its parts. F# makes so many (unnecessary) problems go away that programming is simply a lot more fun and productive. It's not an individual feature that makes it so great, but how they all fit together and how some (bad) programming ideas have been purposefully discouraged (e.g. null
, mutability/assignment, arbitrary file ordering, mutually recursive types, implicit interface implementations, etc.)
I guess the most impactful cultural push for F# within the .NET ecosystem would be if Microsoft would say "Listen folks, we decided to drop support for C# and VB.NET. We are very sorry, but we realized that F# is so much better. So, please use F# from now on. Here is a new base library and all our tools are now optimized for F# only. What is that backwards-compatibility you speak of? We have build everything from scratch. You just need to re-learn everything." but I understand that this is wishful thinking since that would simply hurt the .NET ecosystem overall and Microsoft's image/customers.
e.g. your boss is not deeply technical and hates you talking about these language features he/she doesn't understand
I've actually experienced this personally with a technical decision maker 😄. The boss (responsible for business decisions) was actually really impressed with F#, but he had to trust the technical decision maker.
@GiorgioG
I hope folks don't take the above as just idle complaining - I'm optimistic about F#. I suppose I'm just being impatient ;)
Same here. I would not be spending so much time in this discussion if I wasn't already in love with F# and its potential. I think "impatience" is the right word. F# 4.1 is really awesome and I know that we will get the tooling eventually right, but I want it sooner than later 😉.
Edit: Improved wording including title and description of contents of referenced article. Also included quotes from article.
On a slightly different but still tooling-related note, one of the reasons I'm still holding back from introducing F# to my coworkers is documentation. Specifically, the documentation of FAKE, which is quite hard to find things in even when you know what you're looking for. Since FAKE is pretty much the de facto standard build tool for F# projects (unless they were written by @haf, who prefers Rake), that's the tool that I'll be recommending. I don't expect to have much trouble getting them to use Paket (if I can persuade them to use NuGet packages at all — see my earlier comment), but FAKE is another story. The documentation that has been written for FAKE so far is great, but it's a little inconsistent (e.g., the Getting Started tutorial recommends Paket, but the first non-tutorial link underneath it is "NuGet package restore", which doesn't mention Paket at all. Huh?), and it has serious discoverability problems. That is, if I was a newbie to FAKE, I would have no idea where to go to find the function I needed.
The easiest solution I can see to that particular problem would be to build a function index, so I've opened https://github.com/tpetricek/FSharp.Formatting/issues/431 to discuss that idea. But I'm also mentioning it here, because I think this may be one of the barriers to adoption. Take a look at this series of Stack Overflow questions, all from the same user, and consider how many other users would have given up after the second or third roadblock:
If we want to see F# and its excellent tools being adopted, we need to make it easy for people to figure out how to use those tools, which means documentation that isn't just good, or even great, but just as excellent as the tools themselves are.
@rmunn That's true. I'd reckon @forki would appreciate a few people becoming co-maintainers on FAKE with a view to documentation and issue management. It's basically very stable and its a good time for people to come in and work on those perspectives.
I'm already planning on doing some work on the FAKE documentation, but currently since I haven't yet persuaded my coworkers (and more importantly, my boss) to use F#, I can only justify working on F# stuff in my limited evenings-and-weekends time. But there's also the RFC I need to write for my "simple arithmetic in numeric literals" suggestion, and then I need to start reading the F# compiler code to figure out how to implement it...
There are lots of places I want to contribute, and I'll be able to get to all of them eventually. The key is figuring out which one is the highest priority at this moment. :-)
I was just about to reply to issue "How to drive F# Adoption - Part 1" (#798) when I noticed that it disappeared. Same for Part 2 (#803) and Part 3 (#809). Why do issues get deleted?
Edit: Part 1 - 3 are back up again.
Anyway, I know I am late to this discussion, but I find it still very relevant. There is a great presentation on mainstreaming a programming language by the creator of Elm. He seems to be right since Elm has become relatively popular in the web community in a really short time despite being completely different from what web developers are used to (e.g. Haskell-like syntax and semantics, new concurrency abstractions, new architecture). He did that with great tutorials, usable samples and a frictionless out-of-box experience.
I think @dsyme and @swlaschin have summarized the most important issues driving F# adoption. When it comes to mainstreaming F#, I feel that the following areas have the highest impact:
Awareness
Microsoft needs to put their money where their mouth is. F# should not be a second-class .NET language that is always put behind C# and VB in terms of priority, support and resources.
Microsoft and the F# community also need to change their sales pitch.
Not:
But:
For small problems. For large problems. For any domain. We need to make clear that F# is better than C# in every aspect as a language (which it is!). And this is why F# does not need as much tooling as C#, because it is simply more expressive and you can solve problems directly without fiddling around with XML or poorly designed imperative OO APIs. This is not about not-being-nice, but about being honest.
Out-of-box-experience
As Scrott Wlaschin said, the out-of-box-experience must be frictionless (single all-you-need install, no show-stopping compiler bugs or tooling bugs, good project system, working samples, and up-to-date tutorials). The F#-community has to take full control of the out-of-box-experience to make this a reality.
We need to force Microsoft to take F# seriously by making its out-of-box-experience better than C# (imagine that for a second). Only when Microsoft think they are about to miss the train on an opportunity, do they put their gigantic resources behind a technology (see iOS -> WinRT | cloud -> Azure | Docker -> Windows Containers on Windows Server | virtual reality headsets -> Holo Lens | Xamarin -> .NET Core). Only if Swift overtook C# in terms of usage, would they recognize that they have been sitting on an underappreciated gold mine.
Guidance
Don Syme makes a great point (as always) about the upstack technologies that drive F# adoption all being home-grown F# projects by the open souce F# community as opposed to .NET projects by Microsoft (where .NET is synonymous with C#). That's because these F# projects take advantage of F# as a language instead of being held back by C#'s shortcomings.
I actually think that F# needs to get away from trying to be just another .NET language that fits into the Microsoft technology stack of much-delayed and frequently dropped technologies that are unusable without amazing tooling (which C# has and even needs because it itself is not expressive enough).
Scrott Wlashin is right (again). Officially discourage legacy Microsoft infrastructure tools for .NET like VS project files, NuGet and MSBuild, which have already sucked before F# had to rely on them. F# has much better alternatives now (Paket, FAKE, but still needs a good F#-only project system). VS Code with ionide seems to have overtaken Visual Studio with VFT in terms of usability and functionality in a very short time(!). I have the feeling that Microsoft is actually holding the F# community back by diverting its limited resources and focus to integrating with existing Microsoft products instead of efficiently developing new and better solutions.
Target Audience
The target audience should not be existing C# programmers. C# programmers will only consider F# to be a serious alternative when Microsoft tells them to. Until then, most programmers that might be interested in F# are programmers that are already interested in functional programming, which might also end up with Swift, Haskell, Scala, Clojure, Rust, Elm, etc if disappointed with the out-of-box experience of F#. Again, the F# upstack technologies can only pull-in developers from other communities when F# has the best upstack technologies in a certain domain.
Portability
F# absolutely needs to run out-of-the-box on the future platforms of .NET that enable cross-platform development to stay relevant: .NET Core, Xamarin platforms and .NET Standard Library 1.0. This is why I think that it is a mistake that Microsoft.FSharp.Core.netcore will require .NET Standard Library 1.5 (#1217) as opposed to .NET Standard Library 1.0, which runs on .NET Core, Xamarin and every other .NET supported platform. There should be a single F# Core version that complies with .NET Standard Library 1.0 instead of having multiple versions for different platforms. Having a single F# Core version will make it much easier to maintain and avoid bugs like the inlining bug with F# 3.1 and PCL profile 259.
I also think that WebAssembly is going to change everything. What if WebAssembly becomes the primary execution target for F# in the future?