dotnet / fsharp

The F# compiler, F# core library, F# language service, and F# tooling integration for Visual Studio
https://dotnet.microsoft.com/languages/fsharp
MIT License
3.82k stars 773 forks source link

How to drive F# Adoption - Part 4 #1339

Closed 21c-HK closed 7 years ago

21c-HK commented 7 years ago

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:

"F# is best for niche domains like data science, machine learning, or financial trading, etc."

But:

"F# is better than C# - for everything!".

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?

dsyme commented 7 years ago

@21c-HK I think something bad is happening to GitHub in the last few hours. Multiple historical pull requests have disappeared from https://github.com/dsyme/visualfsharp/pulls, for example

21c-HK commented 7 years ago

@dsyme Are you sure this is GitHub's fault? I find it curious that #797 and #799 are still there and only #798 (Part 1) is missing. #804 is also still there but #803 (Part 2) is missing. #808 and #810 are still there and only #809 (Part 3) is missing. This looks to me that these issues were deliberately removed.

Edit: Part 1 - 3 are back up again. By the way, does anyone know what happened?

cartermp commented 7 years ago

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.

What new and better solutions do you have in mind here? For example, Azure is an existing Microsoft product where we could have significant integration with in the form of Fluent F# APIs for new services. I think this could help F# adoption significantly.

The target audience should not be existing C# programmers.

I find myself agreeing with the premise that we shouldn't be trying to cannibalize the C# development pool. I suppose there are plenty of C# developers out there who mesh quite well with the idea of Functional-First programming (as opposed to Object-Oriented-First), but I do think that the biggest bang for our buck in terms of attracting people to F# will be in the form of developers out there who already love functional programming.

This raises a question, though - of that crowd, who is best to attract? I'm not a strong believer that existing Haskell and Scala devs will come rushing to F# the instant it's got full support on .NET Core, for example. Things like the lack of Higher-Kinded Types might feel like a downgrade to people who are used to using them. Would it be an attractor to add more "Type Theory Features" to the language?

I've always seen F# as one of the best (if not the best) "blue collar functional programming language". It's dead simple to write good, clean functional code for solving real-world problems, and that's largely because the unique language features F# has and the tooling you can use are some of the best out there for functional programming (if not the best). How could this aspect of F# be made even more awesome?

Personally, I'm a lover of ad-hoc polymorphism, find F# lacking in this area (even compared to C#!), and would love to see some proposals on how to improve it. But that's just my own opinion - I generally prefer ad-hoc polymorphism to pattern matching (even though I love pattern matching). Is this true for other people? I have no idea. I'm kind of weird in that I love multiple ways to attack a problem - ad-hoc polymorphism and pattern matching - and will use one or the other when it "feels" right.

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.

This isn't a strategic decision - it's a point-in-time technical decision. The guidance for any kind of package authoring is to pick the lowest version of the .NET Standard that you can get away with. We're certainly not putting this one in the bag as complete. I'd love to see this get lowered to the lowest .NET Standard version that we can have. This is something we'll look at again - but right now, the top priority for FSharp.Core is getting 100% of the APIs working on .NET Core and bringing it out of alpha.

21c-HK commented 7 years ago

@cartermp

What new and better solutions do you have in mind here?

I was referring to the home-grown F# technologies mentioned earlier. For example:

I'm not a strong believer that existing Haskell and Scala devs will come rushing to F# the instant it's got full support on .NET Core, for example. Things like the lack of Higher-Kinded Types might feel like a downgrade to people who are used to using them.

You are right. This is also a worry of mine. Higher-kinded types is probably the only language feature that would have an effect on F# language adoption, because Haskell and Scala programmers think that a language without higher-kinded types cannot be taken seriously.

Personally, I'm a lover of ad-hoc polymorphism, find F# lacking in this area (even compared to C#!), and would love to see some proposals on how to improve it. But that's just my own opinion

How do you find F# lacking in this area? As far as I know, the only feature missing from F# is implementing the same interface multiple times on the same type with different type arguments. This situation was slightly (but not satisfactorily) improved in F# 4.0. I personally find ad-hoc polymorphism overrated. Operator overloading and method overloading have their uses cases, but instead of using interfaces there is usually a better type-based or functional solution (depends on the concrete problem). And member constraints in F# provide extremely powerful and flexible structural ad-hoc polymorphism, if needed, that C# does not even have.

This isn't a strategic decision - it's a point-in-time technical decision.

This is what I find confusing. F# Core today has a version for PCL profile 259. PCL profile 259 will comply with .NET Standard Library 1.0. .NET Core 1.0 will require .NET Standard Library 1.6, which means that projects compliant with .NET Standard Library 1.0 will run on .NET Core 1.0 (because .NET Standard Library 1.6 will be backwards-compatible with .NET Standard Library 1.0). So transitively, F# Core today should be able to run a .NET Core that is compliant with any version of the .NET Standard Library. Could you please elaborate why this does not work?

cartermp commented 7 years ago
  • Paket instead of NuGet
  • FAKE instead of MSBuild
  • Suave or WebSharper instead of ASP.NET
  • MBrace.Azure instead of some fluent F# wrapper around an OO-API of Azure
  • a new F#-only project system instead of VS project systems (which was holding back VFPT), project.json (which was dropped by Microsoft recently) and the new Common Project System (which is C# and VB only, and not open source)

Why the dichotomy? I want to live in a world where I can pick between a variety of options, not just the handful of tools blessed by some members of the community. Using the web as an example, I'd probably pick Suave if I had the choice because I think combinator-based routing is brilliant for building a web API, but if I had to choose ASP.NET Core in the workplace for whatever reason, I'd be a lot happier if there was some story for F# in place for that rather than having no option at all.

That's the key value proposition here - choice - not being forced down a path away from Microsoft tech.

But I think there's two sides to that coin. We at Microsoft have to do a better job of acknowledging the fact that there are great OSS projects out there, and we can attract people to .NET and .NET languages by highlighting that. Microsoft has been traditionally awful at this, and it's something I'm personally pushing for internally, with some success already (such as suggesting Ionide in our official documentation). It's a matter of keeping momentum for OSS going and trying to snuff out any perpetuation of that nasty NIH syndrome.

How do you find F# lacking in this area?

Long story short, every time I write a pattern match --> dispatch function, I end up missing Clojure protocols. This is purely my own opinion and my own preferred way of doing things. I'm happy to start a discussion elsewhere so as not to bog down this thread with opinionated discussion about potential language features.

So transitively, F# Core today should be able to run a .NET Core that is compliant with any version of the .NET Standard Library. Could you please elaborate why this does not work?

Unfortunately, the interplay between the .NET Standard and various implementations isn't quite baked, so it's kind of confusing. Yes, any of the versions of netstandard1.x run on .NET Core, but we're choosing not to optimize that at this time because we don't have all of FSharp.Core in working order on .NET Core yet. The easiest way to get everything running there is to have access to the most APIs on .NET Core, thus the highest version of netstandard1.x is chosen for now. We want to lower this once we can bring FSharp.Core out of alpha.

21c-HK commented 7 years ago

Edit: Emphasizing that defaults matter and more details why Visual Studio Code with ionide would be a good default development environment.

Why the dichotomy? I want to live in a world where I can pick between a variety of options, not just the handful of tools blessed by some members of the community. [...] That's the key value proposition here - choice - not being forced down a path away from Microsoft tech.

I think we have lost context here. My posts in this thread are not about OSS vs. Microsoft. My posts are about what I think would have the most impact in driving F# adoption. One factor was a frictionless out-of-the-box experience that is competitive with or better than C#. Microsoft in the past has not been willing to make this happen for F# (while it seems that F# on .NET Core might be another story). This is why @swlaschin and I suggested that the F# community needs to take full control of the out-of-box experience to achieve this goal.

As Don Syme said earlier:

It's well known that the defaults matter. They really, really matter.

Part of this would be giving new F# developers guidance on how to have the best development experience with F# by making Visual Studio Code with ionide (or Atom with ionide, but Atom is not that great) the default development environment. Here is why:

  1. Cross-platform (removing resistance to reach more developers)
  2. Leverage (more developers means more improvements)
  3. Speed (less dependence on VS means faster improvements)
  4. Integration (already integrates the best infrastructure tools available for F#: Paket, FAKE)
  5. Familiarity (featuring a pimped up command-line probably appeals to many open source developers)

Compare this page with this one. Which one looks more appealing to open source developers or developers in general? Even Microsoft would benefit from this because Visual Studio Code is still branded with "Visual Studio" and is living proof of the "new Microsoft".

And Don Syme has pointed out how attractive home-grown F# upstack technologies have become. It's not that they compete directly with Microsoft products, but that they stand on their own as really elegant solutions to certain problems. Projects like these are what create the required attention in the open source community to pull-in developers from other functional languages to grow the F# community. The still small F# community has nothing to gain from diverting its limited resources to integrating with existing Microsoft products; unless we do have something to gain from it in which case we do integrate with them (e.g. MBrace <-> Azure, Paket <-> NuGet). On the other hand, F# does have a lot to gain from Microsoft's efforts in bringing .NET to more platforms (e.g. .NET Standard Library, .NET Core, purchase of Xamarin) and making F# run on these platforms. So this is definitely appreciated by the F# community, but at the same time we need to be focused (and selfish) while we are small.

I'm personally pushing for internally, with some success already (such as suggesting Ionide in our official documentation).

Thanks! That's awesome.

dsyme commented 7 years ago

The .. .F# community has nothing to gain from diverting its limited resources to ...;

I generally recommend not taking a single point-of-view on what's worthwhile for a diverse community.

The F# contributor and user base is made up of many different perspectives and interests. For some, indeed many, integration with other .NET technologies, tools and commercial products is key and they are willing to put a lot of time into this. This helps to grow adoption and mindshare, and is part of the bread and butter of life in the software world. So there are definitely people with a lot to gain from putting time into working with standard .NET toolchains. Not everyone, but many.

There is definitely also a growing "F# centric" point of view with matching tools, which is also helping to grow F# adoption and mindshare.

dsyme commented 7 years ago

@cartermp

Long story short, every time I write a pattern match --> dispatch function, I end up missing Clojure protocols. This is purely my own opinion and my own preferred way of doing things. I'm happy to start a discussion elsewhere so as not to bog down this thread with opinionated discussion about potential language features.

Could you write this up in a suggestion on fslang.uservoice.com please? Or send me private email. Or a link.

thanks!

7sharp9 commented 7 years ago

I think the point on FSharp.Core targeting .Netstandard one is a really good one, F# should make arrangements to make FSharp.Core hell go away.

7sharp9 commented 7 years ago

Personally, I'm a lover of ad-hoc polymorphism, find F# lacking in this area (even compared to C#!), and would love to see some proposals on how to improve it. But that's just my own opinion

Row polymorphism aka duck typed record semantics? That would my my vote. (If I had any left :-) )

Krzysztof-Cieslak commented 7 years ago

VS Code with ionide seems to have overtaken Visual Studio with VFT in terms of usability and functionality

Just no.

7sharp9 commented 7 years ago

vscode is pretty good, but lacks a few things like metadata viewer but not much more. I don't use VS or XS at the moment.

21c-HK commented 7 years ago

@dsyme

Could you write this up in a suggestion on fslang.uservoice.com please?

I think what @cartermp wants are interfaces that support retroactive extension of existing types since this is what is special about Clojure's protocols, which dispatch dynamically on the type of the first argument. Swift's protocols also support this through a run-time extension mechanism they call "extensions", which also dispatch dynamically on the signature of the member. Haskell's type classes are also very similar, but dispatch statically on the type of multiple parameters and the return type, which is even better.

There are already feature requests on fslang.uservoice.com very similiar to this:

pattern match --> dispatch function

I am not sure what exactly the requested feature has to do with pattern matching. Could you elaborate?

7sharp9 commented 7 years ago

The big question everyone is thinking is who is the secret identity of @21c-HK :-)

bryanedds commented 7 years ago

Clojure protocols are the best! Unfortunately, I don't think they can be statically typed :(

cloudRoutine commented 7 years ago

@21c-HK

a new F#-only project system instead of VS project systems (which was holding back VFPT),

While I would certainly love a new project configuration file format (preferably TOML based), as a maintainer of VFPT I'm not sure what you're referring to being held back.

VS Code with ionide seems to have overtaken Visual Studio with VFT in terms of usability and functionality in a very short time(!)

As one of the Ionide maintainers I'm sorry to say this really isn't the case (although it is the long term goal). Features for managing your projects and solutions is sorely lacking and a huge headache for us and our users, the startup time of completions can be fairly finicky, it requires a fair amount of perquisite installations due to upstream dependencies, the REPL support is read-only, the build integrations with FAKE require a fair amount of setup which isn't great for someone totally new to F# and .Net, we're forced to rely on regex based language parsing so the syntax highlighting is nowhere near as good, we don't have any record stub or interface method scaffolding, no scope based outlining, and the list goes on.

Quite frankly Visual Studio + VFPT or Xamarin is (at the moment) the best starting experience for a new F# developer. When Ionide reaches a better level of feature parity with them it'd be great to have a page on MSDN too about getting started with F# in vscode, but I don't think we're there yet.

And even then it won't always be the best tool for the job, there are some projects and tasks where I use vscode + ionide and others where I prefer VS + VFPT, it's about using the right tool for the job while weighing the requisite trade-offs. I think the important thing is to make it easier for new users to see what those options are and when they might use them while making the experience as frictionless as possible for ALL of them. Which isn't an easy task and there aren't a lot of people working on it, but I think about where we were a year ago in terms of F# tooling and we've definitely come a long way.

21c-HK commented 7 years ago

@cloudRoutine

as a maintainer of VFPT I'm not sure what you're referring to being held back.

The Folder Organization page of VFPT says the following:

This feature is disabled by default. Because there are known issues with F# Project System in Visual F# Tools, folder organization may not work 100% correctly in all cases.

  • We do not advice you to introduce complicated folder structure within F# projects.
  • You should keep number of folders within your project as low as possible.

I have used this feature and had me scratching my head for a while because the VS project view sometimes did not match what was being written to the F# project file. I find folder support to be an essential feature for non-trivial projects.

we're forced to rely on regex based language parsing

Is this because it needs to be compiled to JS? Does that prevent you from using FParsec for parsing?

cloudRoutine commented 7 years ago

@21c-HK those Folder organization issues are also related to dealing with internal VS APIs for solution and project management, so I wouldn't blame the msbuild xml configuration format for all of it.

Is this because it needs to be compiled to JS? Does that prevent you from using FParsec for parsing?

It's because of how the editor extension API is designed and right now we're forced to use the old textmate approach. If it let us apply CSS tags to spans in the editor pane and define a CSS style for syntax highlighting we could use the same approach as VFPT by connecting VFPT.Core to FSAC and using it's lexer, but at the moment we can't. We wouldn't use FParsec.

7sharp9 commented 7 years ago

Folder support in XS is also slightly buggy on the edge cases, file ordering seems to be a sticking point on tooling.

21c-HK commented 7 years ago

There are obviously different opinions on what is currently the best development environment for F#. Could we gather a few opinions on what your ideal F# development environment would need to feature? I'll start with my wish list:

So basically the best of Ionide, Visual F# Power Tools and Visual Studio ;-). And of course, all of these features need to be so fast as to not slow down my typing or train of thought ;-).

Have I forgot anything? Is something missing that you find essential?

@cloudRoutine and other IDE extension maintainers: Are there technical limitations in Visual Studio Code, Visual Studio or Atom that prevent the implementation of any of these features?

cloudRoutine commented 7 years ago

@21c-HK There are different limitations for Atom and vscode and we've already planned to implement all of your list that's possible at the moment. As the vscode and atom extension APIs evolve and expand we'll fill in the remaining gaps.

These kinds of comments/suggestions are better directed at the individual tooling project repos as that's where most of these features will be implemented.

7sharp9 commented 7 years ago

The limitations are mainly people spending there time doing the work. aka oss

7sharp9 commented 7 years ago

I don't see Microsofts limited investment as a problem as long as community contributions are not held up due to bottlenecks in merging pull requests. I mean there hasn't been much change in the 6 or so years I have been involved, I don't see this changing anytime soon.

HoraceGonzalez commented 7 years ago

Linux support is the linchpin, IMO. Porting the existing community ecosystem to .NET Core (ie. Paket, Fake, Suave, etc...) is even more critical to adoption than the language itself.

7sharp9 commented 7 years ago

With MS dragging their feet on a full viable release of dnc and ultraslow uptake within F# I reckon come back in 2017 to check progress.

HoraceGonzalez commented 7 years ago

Yes. I'm optimistic that some of the beta/ctp/rc dust will settle after the 1.1 release this fall, especially since project.json will be retired.

eriawan commented 7 years ago

Yes. I'm optimistic that some of the beta/ctp/rc dust will settle after the 1.1 release this fall, especially since project.json will be retired.

Absolutely agree! I personally dislike JSON project model. This is one of the reason I prefer to use .NET Core in its release instead of previous always using JSON project.

I hope F# tooling support for .NET Core in Visual Studio should always depend on MSBuild project model.

zpodlovics commented 7 years ago

Some of them may already in the pipe thanks to @dsyme (eg.: fixed, struct tuple, etc), but it would be good to have the same or similar high performance language features available in F# too (at least in parity with the C# features):

https://github.com/dotnet/roslyn/issues/10378

7sharp9 commented 7 years ago

I hope F# tooling support for .NET Core in Visual Studio should always depend on MSBuild project model.

Ive always hoped the opposite, msbuild and proj files have always been a Charlie Foxtrot.

eriawan commented 7 years ago

@7sharp9

Why? I know it's been quite a mess but afaik large codebases in most enterprise apps (especially in my country) depends on it. Could you elaborate more on the reason why it's the opposite?

HoraceGonzalez commented 7 years ago

@eriawan, I think it has a lot to do with the fact that the MSBuild language/files are xml-based. Complicated build scripts can get unwieldy fairly quickly, especially when they reference custom targets.

I agree though that sticking with MSBuild and the existing project file format was a good decision for the time being. The transition from a monolithic .NET Framework to a modular .NET Core was already pretty jarring. Additional tooling adds more novelty. Keeping the foundational build tools around will soften the landing a little bit, allowing F# devs to continue to use FAKE/Paket (once ported) without much interruption. Eg. as @forki pointed out per this comment: https://github.com/fsprojects/Paket/issues/1230#issuecomment-157324351, coupling between the project system and top level dependency management in the project.json format made Paket integration practically unworkable.

As much as we'd all like for MSBuild script to go away, it's critical that MS create an hospitable environment for existing .NET projects in .NET Core.

Krzysztof-Cieslak commented 7 years ago

It's not about XML, XML is not perfect but file format in the end doesn't matter.

21c-HK commented 7 years ago

Ive always hoped the opposite, msbuild and proj files have always been a Charlie Foxtrot. ... I think it has a lot to do with the fact that the MSBuild language/files are xml-based. Complicated build scripts can get unwieldy fairly quickly, especially when they reference custom targets. ... It's not about XML, XML is not perfect but file format in the end doesn't matter.

Not to further derail the thread, but I think you are both right. 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#).

"My tenth rule of programming":

Any sufficiently complicated XML-based format contains an ad hoc informally-specified bug-ridden slow implementation of half of a proper declarative DSL.

7sharp9 commented 7 years ago

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.

All Im saying is there are a better ways, we don't have to bath in the same water if we don't want to.

smoothdeveloper commented 7 years ago

Project files and solution setup (a jargon descending from Visual Studio) and their file format are not the most understood from newcommers.

I'm always advising newcommers to start with scripting in .fsx because it provides great experience starting from a single file, along with the ability to use paket generate-include-scripts command to make it easy to reference nuget packages in scripts, and the ability to load other .fs files, I think this makes a great introductory setup, which is easy to explain and based on simple human editable files (paket.dependencies and .fsx script files).

I've noticed the compiler is able to compile script files, I'm wondering if we shouldn't bake an option for the compiler to also copy the referenced assemblies in the output directory (I haven't found a way to do this).

If we had this, it is not so far stretched to see how a project.fsx could solve most of issues people are encountering when they don't have the "seasoned user of Visual Studio" background.

This could evolve into fs.project file which could be a DSL describing the build of a fsharp project.

21c-HK commented 7 years ago

@smoothdeveloper I think this is a great idea! Imagine being able to use type providers that check the validity of file paths and other dependencies before executing a faulty build script.

smoothdeveloper commented 7 years ago

@21c-HK I'm doing a bit of that already with FSharp.Management and FAKE to build visualfsharp repository: https://github.com/smoothdeveloper/buildvisualfsharp/blob/master/fakebuild.fsx#L102

Krzysztof-Cieslak commented 7 years ago

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.

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)

As I've mentioned several times on Twitter, GitHub and my blog I'd be really happy if we could get new, lightweight project system for F#. And I strongly believe that it would drive F# adoption... especially it could bring more people from communities / ecosystems different than C#.

Krzysztof-Cieslak commented 7 years ago

Unfortunately this repository due to it's nature is probably worse place to discuss similar ideas, anyway ;)

dsyme commented 7 years ago

@Krzysztof-Cieslak I do sort of agree with that, or at least I know what you're saying. The Visual F# IDE Tools are constrained in certain ways - they will tend bias towards interop and consistency with the project file formats supported for other languages in Visual Studio , and are unlikely to lead the charge to a new format. But that's not saying it can't happen.

Of course if another project file format became widely popular in the F# ecosystem then it would be natural for the Visual F# IDE Tools to support it (at least if it could be done in a way that's fully compatible with other goals of those tools, and didn't intrude too much on long term engineering concerns for those tools) :)

HoraceGonzalez commented 7 years ago

And this is the attitude that's been so refreshing about the F# community: let emergent technologies take their place while respecting the common/existing ecosystem.

smoothdeveloper commented 7 years ago

Advertising F# as a viable scripting solution to powershell users is also something which tends to yield positive feedback, got few engaging discussions with IT Admin crowd about scripting and great tooling experience with Visual Studio or VSCode/ionide when things get more involved than few lines of code.

People don't know that F# has a REPL and that it support scripting out of the box.

1284 is a bit blocking though, also #1056.

DemiMarie commented 7 years ago

One direction I would like to see is for F# to stop being held back by the limitations of the CLR. CoreCLR, at least, supports unsafe casts, and even if one needs to stick to verifiable code one can just erase the advanced type system features and insert casts where needed. In other words, use CIL as a portable assembler and insert casts where needed. I suspect that most users of F# have no need for verifiable code (sandboxing in the CLR is basically dead).

DemiMarie commented 7 years ago

One other feature I would like to see in the F# compiler is functional-language related optimizations, such as ones related to lambdas and closures, as well as inlining. Ideally this would be the job of the CLR, but practically the CLR doesn't have the time to do it.

sin8 commented 7 years ago

F# syntax should be rethink from the ground up.. it's clearly bad

choosing int * int => int instead of (int,int) > int int => int => int instead of int > (int > int)

choosing <- instead of =

choosing match obj with "pattern1".. "pattern2".. instead of "on obj "pattern1" "pattern2"

some to prove my point..

this kind of weird unreadable choice of syntax is seen all over the place in f#

i don't care what any functional geek will say, f# could be 100x better by cleaning up the syntax and rethinking all the naming and parts so that they are truly easily readable and writable.

even 'String to define a type of string isnt very readable..

cloudRoutine commented 7 years ago

@DjSinae thanks, but no thanks

sin8 commented 7 years ago

cloudroutine.. so for you int => int => int is more directly readable than (int,int) > int?

this is your code in your reactive ext wrapper

  type ObservableBuilder() =
        member __.Bind(m: IObservable<_>, f: _ -> IObservable<_>) = m.SelectMany(f)
        member __.Combine(comp1, comp2) = Observable.Concat(comp1, comp2)
        member __.Delay(f: _ -> IObservable<_>) = Observable.Defer(fun _ -> f())
        member __.Zero() = Observable.Empty(Scheduler.CurrentThread :> IScheduler)
        member __.For(sequence, body) = Observable.For(sequence, Func<_,_> body)
        member __.TryWith(m: IObservable<_>, h: #exn -> IObservable<_>) = Observable.Catch(m, h)
        member __.TryFinally(m, compensation) = Observable.Finally(m, Action compensation)
        member __.Using(res: #IDisposable, body) = Observable.Using((fun () -> res), Func<_,_> body)
        member __.While(guard, m: IObservable<_>) = Observable.While(Func<_> guard, m)
        member __.Yield(x) = Observable.Return(x, Scheduler.CurrentThread)
        member __.YieldFrom m : IObservable<_> = m
        [<Obsolete("Use Yield. Return will be removed in an upcoming version of FSharp.Control.Reactive.")>]
        member inline __.Return(x) = __.Yield(x)
        [<Obsolete("Use Yield. Return will be removed in an upcoming version of FSharp.Control.Reactive.")>]
        member inline __.ReturnFrom m = __.YieldFrom m

this me why this or something of the sort wouldnt be clearer?

  type ObservableBuilder() =
        .Bind(m: IObservable<>, f: x > IObservable<>) = m.SelectMany(f)
        .Combine(comp1, comp2) = Observable.Concat(comp1, comp2)
        .Delay(f: _ > IObservable<>) = Observable.Defer(_ > f())
        .Zero() = Observable.Empty(Scheduler.CurrentThread :> IScheduler)
        .For(sequence, body) = Observable.For(sequence, Func<_,_> body)
        .TryWith(m: IObservable<>, h: #e > IObservable<>) = Observable.Catch(m, h)
        .TryFinally(m, compensation) = Observable.Finally(m, Action compensation)
        .Using(res: #IDisposable, body) = Observable.Using(_ -> res, Func<,> body)
        .While(guard, m: IObservable<>) = Observable.While(Func<> guard, m)
        .Yield(x) = Observable.Return(x, Scheduler.CurrentThread)
        .YieldFrom m : IObservable<> = m
        [Obsolete("Use Yield. Return will be removed in an upcoming version of FSharp.Control.Reactive.")]
        inline _.Return(x) = _.Yield(x)
        [Obsolete("Use Yield. Return will be removed in an upcoming version of FSharp.Control.Reactive.")]
        inline _.ReturnFrom m = _.YieldFrom m
sin8 commented 7 years ago

in my opinion if they are use every 2 lines.. the "member", "let" and "fun" keyword are "noise" in the syntax..

the parser should be more intelligent and understand the context..

let dataString = 
        data 
        |> List.map (box>>string)
        |> List.toArray 
        |> String.concat ","

could be cleaner like

dataString = data  > map (box>>string) > toArray > concat ","
cloudRoutine commented 7 years ago

@DjSinae computation expression builders have a specific syntax that they need to follow so this is a bad example (also it's not code that I wrote, try using git blame in the future 😜)

int -> int -> int means something fundamentally different from int * int -> int, you might want to familiarize yourself with currying/partial application and other foundational concepts of functional programming before deciding whether particular syntactic decisions in the language are good or not.

ML has been around just about as long as C, just because something is new to you doesn't mean that it's actually new.

btw - put code in your comments between " ``` " so it renders properly, proper markdown makes it nicer for everyone to read

sin8 commented 7 years ago

look you clearly don't want to understand my point.. stay in you're f# bubble then.. i don't have time to loose

and sorry i fixed what i was saying so why choosing

int * int => int instead of (int, int) > int int => int => int instead of int > (int > int)

all the doc is crippled with this ... it would be 10x more understandable and readable the way i'm proposing.