F# Language

This User Voice was for suggestions about the future evolution of the F# Language and Core Library.

I suggest we ...

You've used all your votes and won't be able to post a new idea, but you can still search and comment on existing ideas.

There are two ways to get more votes:

  • When an admin closes an idea you've voted on, you'll get your votes back from that idea.
  • You can remove your votes from an open idea you support.
  • To see ideas you have already voted on, select the "My feedback" filter and select "My open ideas".
(thinking…)

Enter your idea and we'll search to see if someone has already suggested it.

If a similar idea already exists, you can support and comment on it.

If it doesn't exist, you can post your idea so others can support it.

Enter your idea and we'll search to see if someone has already suggested it.

  1. Allow the addition of operators in type extensions, and also operators on internal types

    This is currently not allowed:

    type Foo with
    static member (+) (foo1, foo2) = foo1.Bar + foo2.Bar

    80 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    5 comments  ·  Flag idea as inappropriate…  ·  Admin →
  2. 67 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    under review  ·  4 comments  ·  Flag idea as inappropriate…  ·  Admin →
  3. Allow Unicode symbols to be used as operators

    Suggestion moved from https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2314078-allow-unicode-symbols-to-be-used-as-operators

    It would be great to define mathematical operators (e.g. ∀, ∑, ∩) in F#, and be able to use other Unicode symbols (such as arrows) in operators as well. So instead of saying

    let inline (!++) xs = xs |> Seq.sum

    you could say

    let inline (~∑) xs = xs |> Seq.sum

    Writing "∑myList" is much, much easier on the eyes and brain than trying to figure out what "!++myList" does.

    76 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    16 comments  ·  Flag idea as inappropriate…  ·  Admin →
  4. Make .Tag and .Is* discriminated union properties visible from F#

    The .NET class that encodes a discriminated union has `.Is* : bool` properties, for example this:

    type Foo = A | B

    has the following:

    member IsA : bool
    member IsB : bool

    They are hidden from F#, but they could actually be quite useful. I regularly find myself writing something like this:

    List.filter (function A -> true | _ -> false)

    when I could write:

    List.filter (fun x -> x.IsA)

    15 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    5 comments  ·  Flag idea as inappropriate…  ·  Admin →

    This proposal is “approved in principle” for F# 4.0+. It would make a good addition to F#. (I don’t think the loss of purity (e.g. wr.t. ordering of union cases) is a critical problem and I believe you can turn of the DefaultAugmentation in any case)

    Some technical issues may need to be ironed out during implementation.

    If this is done, the Tag properties present on these types should also be revealed, that is covered by a separate item.

    An implementation and testing would need to be provided by someone in the F# community (possibly including Microsoft or Microsoft Research, though not limited to them).

    Implementations of approved language design can now be submitted as pull requests to the appropriate branch of http://github.com/Microsoft/visualfsharp. See http://fsharp.github.io/2014/06/18/fsharp-contributions.html for information on contributing to the F# language and core library..

    I’d be glad to help guide people through the implementation process.

    If you…

  5. Allow n partitions for ActivePatterns instead of a max 7

    Active patterns can only have seven partitions (see: http://msdn.microsoft.com/en-us/library/dd233248.aspx)

    It would be good if this was a stylistic constraint that could be overridden if desired.

    For example, if active patterns are getting used to split up XML nodes meaningfully, you aren't in control of how many nodes sensibly fit into the top level.

    23 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    4 comments  ·  Flag idea as inappropriate…  ·  Admin →
  6. Allow type providers to generate types from other types

    There are occasions where it would be extremely useful to generate types from other types.

    As an example, F# interop with NHibernate is very clumsy simply because it's difficult to express types of the sort:

    // C# record class
    public class MyRecord
    {
    public virtual int Id { get; set; }
    public virtual string Description { get; set; }
    // etc...
    }

    It would be very compelling to be able to represent these as F# record types, but the CIL code generated for F# records is incompatible with NHibernate.

    Perhaps it could be possible, using a type provider, to generate…

    116 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    planned  ·  6 comments  ·  Flag idea as inappropriate…  ·  Admin →
  7. Implement monadic getters and setters

    The get/set syntax for F# is very cool, but it has an issue: sometimes, the property we would like to get and set is only available through a workflow/monad, like the async workflow.

    Thus, I would like to alter the typechecking rules for getters and setters. This is what they are right now (pseudocode) for the Async monad:

    Property x : Async<'a>
    get : unit -> Async<'a>
    set : Async<'a> -> unit

    IndexedProperty x : 'k -> Async<'v>
    get : 'k -> Async<'v>
    set : 'k -> Async<'v> -> 'unit

    This is what I would like to see made possible:

    3 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    2 comments  ·  Flag idea as inappropriate…  ·  Admin →
  8. Implement Syntactic Macros

    At least give it a try in a private branch, and upon success, enable them publicly with a compiler switch initially.

    453 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    38 comments  ·  Flag idea as inappropriate…  ·  Admin →
  9. Support C#-like Anonymous Types in F#

    Commonly I want to return some named values, or sequence of named values, in some expression. Currently I am forced to either go through the additional effort of defining a type, or use a tuple (with its associated error-proneness if there are multiple values of the same type). Anonymous record types would be very useful and would eliminate one of the areas of additional verbosity compared to C#.

    215 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    under review  ·  18 comments  ·  Flag idea as inappropriate…  ·  Admin →
  10. Additional intrinsics for the NativePtr module

    When interoperating with native code, it would be handy if the NativePtr module included some additional "intrinsic" functions for taking advantage of low-level IL instructions; specifically, I'd like to be able to use 'cpblk', 'initblk', 'initobj', and 'copyobj'.

    It would also be nice to have an easy way of checking for null pointer values.

    Example implementation of these functions:

    [<RequireQualifiedAccess>]
    [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
    module NativePtr =
    [<GeneralizableValue>]
    [<NoDynamicInvocation>]
    [<CompiledName("Zero")>]
    let inline zero<'T when 'T : unmanaged> : nativeptr<'T> =
    (# "ldnull" : nativeptr<'T> #)

    [<NoDynamicInvocation>]
    [<CompiledName("IsNull")>]
    let inline isNull<'T when 'T : unmanaged> (ptr : nativeptr<'T>) =
    (# "ceq" zero<'T> ptr :…

    10 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    8 comments  ·  Flag idea as inappropriate…  ·  Admin →
  11. #package directive to import NuGet packages in F# interactive

    It would be quite useful for F# interactive to support a #package directive to allow NuGet packages to be downloaded from within the REPL. I think it would be best if this directive simply downloaded the package, unpacked it, and automatically included (#I) the correct folder based on the framework version F# interactive is running under (e.g., net45). If a package doesn't include assemblies for the specific framework version F# interactive is using, we'd automatically include the folder for the latest framework version which is compatible; e.g., if running on .NET 4.5 and a package only includes a 'net40' folder,…

    248 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    under review  ·  8 comments  ·  Flag idea as inappropriate…  ·  Admin →
  12. Implement try/fault expressions

    I would like F# to have try/fault expressions. It would work along the same lines as the current try/with syntax, although the 'fault' block would be constrained to a return type of 'unit'. I don't expect the usage of this to be terribly common, but it would be very handy to have for logging purposes.

    To answer the inevitable question, "Why not just use try/with and reraise()?" -- with try/with you're actually catching the exception; unless you remember to call reraise() to terminate all paths in the control flow within the 'with' block, you'll end up swallowing the exception and…

    5 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    4 comments  ·  Flag idea as inappropriate…  ·  Admin →
  13. Allow Implicit Interface Implementation

    F# only supports explicit interface implementation with the price of unnecessary and excessive casting (also causes readability issues), potential confusion when working with other languages, and causes limitation with F#'s OOP that could be resolved without any major language change.

    To expand on this, this post by Mauricio Scheffer describes the issue very well: http://bugsquash.blogspot.co.il/2009/01/implementing-interfaces-in-f.html

    In addition, I'm sure I could argue that people would prefer to just write `identifier.Member` rather than `(identifier :> Type).Member` whenever the member is a signature provided by an interface.
    This repeats quite a bit on average and it is messy, to say the least.

    133 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    10 comments  ·  Flag idea as inappropriate…  ·  Admin →
  14. Make FSharp.Core collection functions for Array.Parallel more regular

    In F# 3.0, lots of standard functions are missing from Array.Parallel including tryFindIndex, exists, forall, filter, tryFind, reduce, minBy, maxBy and tryPick. A mapReduce function would also be useful.

    Efficient implementations of all of these have been described in the F# Journal. http://fsharpnews.blogspot.co.uk/2013/01/parallel-aggregates.html

    63 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    1 comment  ·  Flag idea as inappropriate…  ·  Admin →
  15. Add syntactic sugar for functions ala Scala/Clojure

    Add in shorthand syntax for anonymous functions, even if it is only for single argument functions.

    For example:

    [1; 2; 3; 4] |> List.map (_ + 1)

    As opposed to

    [1; 2; 3; 4] |> List.map (fun i -> i + 1)

    It would be great to have this shorthand so that our anonymous functions are shorter than the C#ers' :).

    37 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    4 comments  ·  Flag idea as inappropriate…  ·  Admin →
  16. Allow extension interfaces

    Rather than just supporting single methods or properties, provide a mechanism by which to implement interfaces on existing types. This could be similar to protocols in Clojure and Elixir.

    92 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    15 comments  ·  Flag idea as inappropriate…  ·  Admin →
  17. Implement IReadOnlyCollection<'T> in list<'T>

    .Net 4.5 has a new type IReadOnlyCollection<'T> and list<'T> (a.k.a. FSharpList<'T>) fits this interface precisely, so I think it should implement it.

    Original on VS uservoice: http://visualstudio.uservoice.com/forums/121579/suggestions/2902147

    3 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    3 comments  ·  Flag idea as inappropriate…  ·  Admin →

    This is approved for inclusion in a future release of the F# core library subject to an implementation.

    A pull request to implement this feature will be necessary and we encourage contributors to submit one with adequate design detail and testing to http://github.com/Microsoft/visualfsharp.

    Discussion of the particular version where this is included can be started once an implementation is available.

    Don Syme, F# Language and Core Library Evolution.

  18. Add support for GADTs

    Generalized Algebraic Data Types essentially extend standard union types to allow different generic instantiations when defined recursively.

    You can see a simple explanation of how they work in haskell here: https://en.wikibooks.org/wiki/Haskell/GADT

    They open the door to such fantastic type safe data structures as heterogeneous lists and so can vastly improve type safety within the language.

    219 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    5 comments  ·  Flag idea as inappropriate…  ·  Admin →
  19. Simulate higher-kinded polymorphism

    F# already has to make trade-offs when doing interop, e.g. it is possible to create a null value for a DU from C#, erased type providers don't work from anywhere but F# etc. Maybe F# could allow for higher-kinded polymorphism within F# code and use dynamic casts at runtime or maybe statically resolved inlining to simulate higher-kinded polymorphism.

    492 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    16 comments  ·  Flag idea as inappropriate…  ·  Admin →
  20. Remove fun keyword from lambda expressions

    Maybe make it optional?
    Otherwise it is more verbose than C#.

    270 votes
    Vote
    Sign in
    (thinking…)
    Sign in with: Facebook Google
    Signed in as (Sign out)
    You have left! (?) (thinking…)
    17 comments  ·  Flag idea as inappropriate…  ·  Admin →

F# Language

Feedback and Knowledge Base