Fsharp: Templates for dev16

Created on 9 Jun 2018  路  29Comments  路  Source: dotnet/fsharp

Updated set of templates

Here is a flat list of templates we should ship in VS 2019:

  • .NET Core console app
  • .NET Core library
  • ASP.NET Core web app (pivots to Empty app and Web API)
  • Tutorial
  • .NET Framework console app (using .NET SDK)
  • .NET Framework library (using .NET SDK)
  • .NET Standard library
  • MSTest test project
  • xUnit test project

I'm not sure what to make of a "Scripting project". Unless it serves a specific purpose, why have one?

Additionally, Xamarin should continue to deliver the existing F# templates.

Original text

In #4977, we cleaned up templates a bit to more easily distinguish between .NET Framework and .NET Core templates. However, I'd like to document what should be delivered for dev16 (Visual Studio 2019).

This is what I have in mind for now, and what I know is definitely capable of being accomplished from a technical and policy perspective:

  • Console App (.NET Core)
  • Console App (.NET Framework)
  • Class Library (.NET Standard)
  • Class Library (.NET Framework)
  • Tutorial
  • ASP.NET Core Web Application
  • MSTest Test Project (.NET Core)
  • xUnit Test Project (.NET Core)

I'm curious what others have in mind.

Suggested by @KevinRansom:

We should have a TypeProvider template. Allowing users to generate a correctly specified TP nuget package.

Suggested by @dsyme:

I would like to see a "Scripting project".

  • drop the user into the pit of success for F# data scripting
  • consider referencing FSharp.Data and perhaps others
  • consider having pre-baked snippets to make web requests, crack JSON, read/search/enumerate files and so on
  • have examples of #r, #load, #r "nuget: Foo.Bar 4.3.5.2"
  • both .NET Core and .NET Framework variations

Separately we could consider a "Math scripting project" referencing

  • FSharp.Charting (but it is Windows-specific)
  • MathNet.Numerics
  • ML.NET

or some updated variation on FsLab components

Area-Infrastructure

Most helpful comment

I would like to see a "Scripting project".

  • drop the user into the pit of success for F# data scripting
  • consider referencing FSharp.Data and perhaps others
  • consider having pre-baked snippets to make web requests, crack JSON, read/search/enumerate files and so on
  • have examples of #r, #load, #r "nuget: Foo.Bar 4.3.5.2"
  • both .NET Core and .NET Framework variations

Separately we could consider a "Math scripting project" referencing

  • FSharp.Charting (but it is Windows-specific)
  • MathNet.Numerics
  • ML.NET
  • or some updated variation on FsLab components

All 29 comments

@cartermp we should have a TypeProvider template. Allowing users to generate a correctly specified TP nuget package.

I would like to see a "Scripting project".

  • drop the user into the pit of success for F# data scripting
  • consider referencing FSharp.Data and perhaps others
  • consider having pre-baked snippets to make web requests, crack JSON, read/search/enumerate files and so on
  • have examples of #r, #load, #r "nuget: Foo.Bar 4.3.5.2"
  • both .NET Core and .NET Framework variations

Separately we could consider a "Math scripting project" referencing

  • FSharp.Charting (but it is Windows-specific)
  • MathNet.Numerics
  • ML.NET
  • or some updated variation on FsLab components

@dsyme I agree that having this sort of stuff in place would be wonderful. However, I'll have to do some work on my end to secure the ability to ship third-party components with first-party templates. Currently this is extremely prohibitive, and while I disagree with the outcome, I see the reasoning given by folks internally to be extremely reluctant to distribute them.

The primary issue is that when an enterprise uses these templates and there are issues with them (e.g., a security issue), then we (Microsoft) are contractually obligated to service them. Especially if we do not control the codebase, this is extremely difficult to do. However, with dev16, things may be able to change. There are ways we could potentially mark something as not covered by the standard SLA you get with in-box things, but without a proper mechanism to do so today, I'm going to be conservative and assume that this will not be possible.

When I get back from Oslo I'll start a thread with relevant folks internally to push on this again.

@dsyme I agree that having this sort of stuff in place would be wonderful. However, I'll have to do some work on my end to secure the ability to ship third-party components with first-party templates.

I understand. Perhaps the template could just have commented-out of #if sections for different common scripting scenarios

@cartermp

  1. I would like to remove the (.NET framework) templates, they are redundent, and the NetSDK is so much better.
  2. If we think the tutorial template is valuable, we should make .NET Core version of it.
  3. .NET framework class library template makes a class library .NET Core template makes a module. So we should add a module project template, and a class library project template.
  4. Item template for F# class, and F# module.

I don't think we can do away with templates that target .NET Framework, but we can create a template that uses the .NET SDK and CPS instead of the current project system.

@cartermp can you explain why we can't remove the .NET Framework template?

the .NET Sdk project property page should probably allow you to specify the TargetFramework (s) since those values are important, and are can only be modified by directly editing the project file.

It's an experience regression to not allow selection of a project targeting .NET Framework in File | New Project, so we can't eliminate that. The best way forward is to replace the desktop templates with .NET SDK equivalents, so we can start to phase out creation of the old style templates.

I see. Sure I'm fine with a NetSDK project that defaults to net472 or net461, that seems like a fine thing.

Agreed.

  1. What do you think about a scripting template?

  2. I wonder if "Class Library" should be named something more F#-like, e.g. "F# Library". No one in the F# world ever uses the name "Class Library".

@dsyme Isn't "Class Library" name changed to something meaningful by user on project creation anyway?
And I doubt the template name itself should be different from the one in other languages, I'd find it more confusing.

@dsyme Isn't "Class Library" name changed to something meaningful by user on project creation anyway?

Yes, the user specifies the name (I think the default is already just "Library1") but I'm talking about the name in the list of templates.

And I doubt the template name itself should be different from the one in other languages, I'd find it more confusing.

I don't understand it at all. Why is it more confusing to be accurate about naming? If C# called it a Widget Library should F# call it a widget library? No.

Why would we use terminology that is innacurate and foreign to F# on the very first screen that potential new F# programmers see? Seriously, F# is F# and should use F# terminology unless there is a very, very good reason not to.

The templates for F# have never been thought through properly from an F# cognitive perspective, and we should really take this chance to do that. I seriously think much of the impression in the .NET world that F# is a "me too wannabe C#" is based on this sort of thing: we should people "Class Library" and they see the bare bones of an F# library and they are confused why they aren't seeing what they think of as a class library. We should call it what it is, a template for creating an F# Library.

F# doesn't even have the keyword "class".... the idea of "class" is de-emphasized in F#..., subsumed by "type" and "module".

I don't understand it at all. Why is it more confusing to be accurate about naming? If C# called it a Widget Library should F# call it a widget library? No.

But it gets compiled to a class library, so it's an accurate naming after all.
I get what you mean and agree in the case for what newcomers see. Probably "Library" name could de-emphasize "class" thing enough while keeping insight about what kind of a project it technically is.

I don't understand it at all. Why is it more confusing to be accurate about naming? If C# called it a Widget Library should F# call it a widget library? No.

Another thing is when creating a project I'd probably first think about project template type and then about language to create the project in. In Rider we keep the selected language on changing template when template for this project type and language combination is available.

Templates                                         Short Name       Language          Tags               
--------------------------------------------------------------------------------------------------------
Console Application                               console          [C#], F#, VB      Common/Console     
Class library                                     classlib         [C#], F#, VB      Common/Library     

screenshot 2018-10-23 at 15 33 00

@dsyme,

probably Library is sufficient for files that produce a .dll

New class, module, interface and enum should probably be item templates, that would mean a Library template that was pre-populated with a module would be a good start.

A script project seems like it might be a useful addition, however, much of the project configuration is currently focused on creating applications and libraries.

One thing a script project could enable is an experience for creating scripts and packaging and deployment of them, including perhaps compilation. However, that will require some thought.

Kevin

A script project seems like it might be a useful addition, however, much of the project configuration is currently focused on creating applications and libraries.

One thing a script project could enable is an experience for creating scripts and packaging and deployment of them, including perhaps compilation. However, that will require some thought.

Yes, that would be good.

Some people do use scripting with a master script and a bunch of #load of library scripts, it scales well and will be very good one #r "nuget..." is there too

I agree with calling it "Library" instead of Class Library. Here's what it could look like in dev16 File | New Project:

> Visual F#
    > .NET Core
        Console app
        Library
        ASP.NET Core Web App
        Scripting project
    > .NET Standard
        Library
        Type Provider Template
    > .NET Framework
        Console app
        Library
    > Test
        MSTest Test Project
        xUnit Test Project
    > iOS
       ... F# iOS templates
    > Android
       ... F# android templates

Not sure I see the point in having .NET Framework variants of a scripting project once everything is up and running on .NET Core. It's impossible to get the full F# component in VS without also installing .NET Core, so we might as well opt people into that one.

It would be great if there was an Azure Functions template. Indeed "Azure Web App" would seem logical from a Microsoft product perspective, I guess the ASP.NET Core App is set to deploy to Azure

Not sure I see the point in having .NET Framework variants of a scripting project once everything is up and running on .NET Core. It's impossible to get the full F# component in VS without also installing .NET Core, so we might as well opt people into that one.

Libraries - still very many libraries are tied to .NET Framework, and .NET Core F# Scripting is in its infancy. I think the script needs to declare .NET Framework v. .NET Core but I'm not sure what @KevinRansom's latest thinking on that is.

I suppose type provider template should go under .NET Standard assuming that's the runtime library. Note the TP template currently depends on source code assets from the TPSDK (or a nuget package if we publish one) so I'm not sure what in-box template policy is for that.

The ASP.NET Core app already includes the Web SDK, which makes it Just Work w.r.t publishing to Azure. This is the design of it. Functions is a bit more complicated, but doable.

I don't quite understand the libraries piece. Perhaps it should be its own node and not under .NET Core nor .NET Framework. Unless you have target-specific dependencies in your script, it should just work regardless of what you're doing in the rest of your project.

In-box is tricky - ideally it would be a NuGet package, but we'd also need to sign the binary and package with Microsoft keys, otherwise it is not acceptable to include. We could include the source file directly, but I'd defer to @KevinRansom on that.

@dsyme, the current shipping product supports type providers with NetSDK projects that look like:

https://github.com/Microsoft/visualfsharp/tree/master/tests/EndToEndBuildTests/BasicProvider

DesignTime Project:
https://github.com/Microsoft/visualfsharp/blob/master/tests/EndToEndBuildTests/BasicProvider/BasicProvider.DesignTime/BasicProvider.DesignTime.fsproj

TypeProvider Project:
https://github.com/Microsoft/visualfsharp/blob/master/tests/EndToEndBuildTests/BasicProvider/BasicProvider/BasicProvider.fsproj

It can be simplified a bit more, if we add into the nuget package a signal that it's a compilertool/type provider using a marker file or some such. The template can carry the providedtypes.fs/fsi for now.

Anyway TPs are pretty much solved.

The template can carry the providedtypes.fs/fsi for now.

We can't do that - ProvidedTypes.fs is an SDK of 15,000 lines of (complex) code with a steady minor bug rate. We can't be copy&pasting that as user code into every user template, we would get a nightmare where the user can neither maintain that code, nor update it, nor even know where to report issues with the code.

TBH I didn't even realise we'd copied it into the tests above though I don't mind that, it's good to snapshot it.

I think my recommendation would be not to have a type provider template in dev16. The TPSDK can document the process for instantiating and it's simple enough.

Agreed.

@dsyme, we can easily suck in the source from a nuget package, similarly to how the FSharpSdk uses paket.

@dsyme, we can easily suck in the source from a nuget package, similarly to how the FSharpSdk uses paket.

Yes, this is an option (we don't yet currently publish a nuget source package for TPSDK).

To do this in a template we would have to

  1. publish that nuget from this repo
  2. localize the code.

probably some other things. Still best off dev16 radar I think as the current template is adequate for now

I updates the set at the top of the issue. I thought about it, and I'm not in favor of a scripting project unless it demonstrates something where F# scripting is uniquely beneficial.

@cartermp -- I'm not sure about that. Developers who use scripting would love to have access to the same type of unified experience as developers who edit/link/debug/build. I think we need to consider what that unified experience might look like for scripters and perhaps build tooling to make it nicer...er.

Today that experience is adding a file to either a project or solution. How would a brand-new project template improve this?

I think we need to think about it. You may be correct that the current experience is perfect for scripters. My guess is that it isn't. However, I don't know right now, what improvements to make, I do think it needs some thought.

As per internal discussion, we'll include the ability to create .NET Framework-based SDK-style projects and "soft-deprecate" the old-style ones. These will be marked with a legacy moniker of some sort to discourage their creation. In a future Visual Studio (VS 17.0) we'll likely deprecate them.

Was this page helpful?
0 / 5 - 0 ratings