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 printfn to support repeated arguments

    Rather than:
    printfn "%i %x %A" mySecretNumber mySecretNumber mySecretNumber

    Perhaps an index argument could be added
    printfn "%[1]i %[1]x %[1]A" mySecretNumber

    1 vote
    Vote
    Sign in
    Check!
    (thinking…)
    Reset
    or sign in with
    • facebook
    • google
      Password icon
      I agree to the terms of service
      Signed in as (Sign out)
      You have left! (?) (thinking…)
    • Code expressiveness: Add loops with test condition in the middle

      Sometimes programmers need to first make a calculation and exit the loop when a certain condition is met. However when the condition is not met there is something else to be done. Hence we need a loop where the test condition is in the middle. That loop was first suggested in 1972 by Ole-Johan Dahl, a Norwegian computer scientist who is deemed to be one of the fathers of object-oriented programming.

      I suggest using the syntax for that loop that requires no new keywords:

      do
      (* indentation to indicate the first part of the loop body *) body-expression
      while test-condition…

      2 votes
      Vote
      Sign in
      Check!
      (thinking…)
      Reset
      or sign in with
      • facebook
      • google
        Password icon
        I agree to the terms of service
        Signed in as (Sign out)
        You have left! (?) (thinking…)
      • Handle null values in Records gracefully instead of crashing with a NRE

        Please see https://github.com/Microsoft/visualfsharp/issues/1044

        Currently, if a nonnull field in a record (e.g. another record, or FSharpList<'T>, ...) is null, .GetHashCode (and potentially other methods) throw a NullReferenceException.

        While these objects are obviously invalid and AFAIK can't be easily created in pure F#, this case sometimes happens out of the control of the user.

        Examples are DataBinding in WPF and Serialization.

        If the external code ever calls .GetHashCode on an object under construction, it will blow up.

        The suggestion is NOT to change anything semantically but to handle null values gracefully where possible to ease the interop with these external libraries.…

        0 votes
        Vote
        Sign in
        Check!
        (thinking…)
        Reset
        or sign in with
        • facebook
        • google
          Password icon
          I agree to the terms of service
          Signed in as (Sign out)
          You have left! (?) (thinking…)
        • 4 votes
          Vote
          Sign in
          Check!
          (thinking…)
          Reset
          or sign in with
          • facebook
          • google
            Password icon
            I agree to the terms of service
            Signed in as (Sign out)
            You have left! (?) (thinking…)
            1 comment  ·  Admin →
          • Add triple-questionmark not yet implemented operator (???) from Scala

            In Scala, there is an operator `???`, which is used as a "Convenient as a placeholder for a missing right-hand-side of a method."

            This is defined as follows:
            def ??? : Nothing = throw new NotImplementedError

            In F# I would imagine that we'd define it something like:

            [<GeneralizableValue>]
            let ???<'a> = raise (NotImplementedException())

            Unfortunately, ??? is not a valid name, which is why a library solution won't solve this problem.

            The major merit of including this in F#, is that it provides a standardized way to declare incomplete parts of the code, allowing users and tooling to detect this.

            You…

            11 votes
            Vote
            Sign in
            Check!
            (thinking…)
            Reset
            or sign in with
            • facebook
            • google
              Password icon
              I agree to the terms of service
              Signed in as (Sign out)
              You have left! (?) (thinking…)
            • Compiler directive for environment variables

              It would be nice to have a compiler directive for environment variables which can be used in string literals.
              This way we can pass different parameters to type providers on a build server.

              [<Literal>]
              let ConnectionString = #env "MY_DB_CONNECTIONSTRING"
              let cmd = new SqlCommandProvider<"...", ConnectionString>()

              4 votes
              Vote
              Sign in
              Check!
              (thinking…)
              Reset
              or sign in with
              • facebook
              • google
                Password icon
                I agree to the terms of service
                Signed in as (Sign out)
                You have left! (?) (thinking…)
              • Can we build a pre-processor so we don't have to use the word: let ? Makes the function name standout and saves typing similar to R ?

                Makes the function name standout and saves typing similar to R, ofcourse if it can be done without breaking something else ?

                f := 3 //or ... rather than
                let f = 3

                4 votes
                Vote
                Sign in
                Check!
                (thinking…)
                Reset
                or sign in with
                • facebook
                • google
                  Password icon
                  I agree to the terms of service
                  Signed in as (Sign out)
                  You have left! (?) (thinking…)
                • Add the (..<), (>..) half-open range operators and (>..<) open range operator (from Swift)

                  I suggest adding the (..<) and (>..) half-open range operators and (>..<) open range operator to the language in order to reduce risks of introducing off-by-one errors in code.

                  There is the (..) closed range operator in F# to generate ranges of consecutive values, but now the language lacks the (..<) and (>..) half-open range operators to generate ranges of consecutive values without the first or last value specified respectively. Furthermore, there is no open range operator (>..<) to generate a range of consecutive values without both the first and last value.

                  Syntax suggested:
                  a) from Swift:
                  1 ..< 10…

                  1 vote
                  Vote
                  Sign in
                  Check!
                  (thinking…)
                  Reset
                  or sign in with
                  • facebook
                  • google
                    Password icon
                    I agree to the terms of service
                    Signed in as (Sign out)
                    You have left! (?) (thinking…)
                    1 comment  ·  Admin →
                  • Add the do .. while loops to the language (from Java, C, C++, C#)

                    I suggest adding the do .. while loops to F#. This feature would improve the expressiveness of the language and facilitate the migration of large codebases to F# from imperative languages such as Java, C, C++, C#.

                    I suggest using time-tested and popular syntax from Java, C, C++, C# (TIOBE TOP 4 languages as of March 2016), but with F#-style indentation instead of {}:

                    do
                    (* indentation to indicate the body of the loop *) body-expression
                    while test-condition

                    The difference between the do .. while loop and the already existing in F# while .. do loop is that do ..…

                    4 votes
                    Vote
                    Sign in
                    Check!
                    (thinking…)
                    Reset
                    or sign in with
                    • facebook
                    • google
                      Password icon
                      I agree to the terms of service
                      Signed in as (Sign out)
                      You have left! (?) (thinking…)
                    • Code clarity: Remove Object Pascal-style for ... to|downto ... do ... loops from the language (from Swift)

                      The for ... to|downto ... do ... loop appears to be a mechanical carry-over from Object Pascal rather than a genuinely F#-specific construct. The for ...to|downto ... do ... loops do not lend themselves to use with sequences and other core F# types supporting IEnumerable interface. It is rarely if ever used in pro-level apps. More F#-typical construction is already available in the language with the for ... in ... do ... loop that has much better readability and expressiveness.

                      Example # 1:
                      // it provides equivalent behavior to: for i = 1 to 100 do ...
                      for i in…

                      4 votes
                      Vote
                      Sign in
                      Check!
                      (thinking…)
                      Reset
                      or sign in with
                      • facebook
                      • google
                        Password icon
                        I agree to the terms of service
                        Signed in as (Sign out)
                        You have left! (?) (thinking…)
                      • 26 votes
                        Vote
                        Sign in
                        Check!
                        (thinking…)
                        Reset
                        or sign in with
                        • facebook
                        • google
                          Password icon
                          I agree to the terms of service
                          Signed in as (Sign out)
                          You have left! (?) (thinking…)
                          1 comment  ·  Admin →
                        • Add (^%) f = f to core library

                          This allows method chaining with sequences etc need no parens:

                          http://stackoverflow.com/questions/36220283/anything-else-similar-to-haskells-in-f-other-than

                          Optionally call it ^$ for Haskell users, though it's not exactly the same as Haskell's $. ^% is (imo) the nicest on the fingers.

                          2 votes
                          Vote
                          Sign in
                          Check!
                          (thinking…)
                          Reset
                          or sign in with
                          • facebook
                          • google
                            Password icon
                            I agree to the terms of service
                            Signed in as (Sign out)
                            You have left! (?) (thinking…)
                            1 comment  ·  Admin →
                          • Add (binary) search function to Map and Set

                            Often in interpolation the nearest collection items to a given value are needed. Map and Set both have a data structure that could be binary searched returning the two nearest neighbours optionally. The function should only be called something like 'nearest' so the implementation isn't exposed.
                            At the moment you would have to replicate the collections to be able to do this.

                            3 votes
                            Vote
                            Sign in
                            Check!
                            (thinking…)
                            Reset
                            or sign in with
                            • facebook
                            • google
                              Password icon
                              I agree to the terms of service
                              Signed in as (Sign out)
                              You have left! (?) (thinking…)
                            • Code clarity: Dot notation for casting objects to interfaces

                              I suggest introducing the dot notation syntax for casting an object to an interface.
                              It would be great to write, for example:

                              this.InterfaceName.methodName(param1, param2, ..., paramN)

                              myObject.InterfaceName.methodName(param1, ..., paramN)

                              instead of:

                              (this :> InterfaceName).methodName(param1, param2, ..., paramN)

                              (myObject :> InterfaceName).methodName(param1, ..., paramN)

                              I think the use of one symbol "." instead of four symbols "(", ":", ">", ")" to convey the same idea can improve F# code clarity.
                              The syntax suggested would be especially useful in the body of methods of classes that implement multiple interfaces.

                              P.S. My suggestion does not mean a breaking change in the F# language. I…

                              5 votes
                              Vote
                              Sign in
                              Check!
                              (thinking…)
                              Reset
                              or sign in with
                              • facebook
                              • google
                                Password icon
                                I agree to the terms of service
                                Signed in as (Sign out)
                                You have left! (?) (thinking…)
                              • Inlined default argument values

                                Instead of

                                member __.Foo(?a: int) =
                                let a = defaultArg a 2

                                it would be great to write it C#-slyle:

                                member __.Foo(?a: int = 2)

                                6 votes
                                Vote
                                Sign in
                                Check!
                                (thinking…)
                                Reset
                                or sign in with
                                • facebook
                                • google
                                  Password icon
                                  I agree to the terms of service
                                  Signed in as (Sign out)
                                  You have left! (?) (thinking…)
                                  1 comment  ·  Admin →
                                • custom set the 'last defined'

                                  Say we implement something like:

                                  type BinaryOp =
                                  | And
                                  | Or
                                  | Not
                                  | None

                                  module test =
                                  let aMatchFunction (s:string option) = match s with
                                  | Some s -> printfn "%s" s
                                  | None -> printfn "(none)"
                                  // Error This expression was expected to
                                  // have type string option but here has
                                  // type BinaryOp

                                  Some of the F# conventions are nice, and it'd be good to be able to stay consistent with them across our code base if we choose. In this case, I feel we shouldn't be forced to adopt the longhand convention of:

                                  Option<string>.None just…

                                  1 vote
                                  Vote
                                  Sign in
                                  Check!
                                  (thinking…)
                                  Reset
                                  or sign in with
                                  • facebook
                                  • google
                                    Password icon
                                    I agree to the terms of service
                                    Signed in as (Sign out)
                                    You have left! (?) (thinking…)
                                  • allow defining function with generic type parameter within another function

                                    I encounter cases where I'd like to define a function taking a generic type parameter within another functions.

                                    type Foo = {Bar: int option; Baz: string option}

                                    let doSomething () =
                                    (**)let writer = Console.Out
                                    (**)let writeOption o =
                                    (* *)match o with
                                    (* *)| Some v -> writer.Write(string v)
                                    (* *)| None -> writer.Write("")
                                    (**)writeOption foo.Bar
                                    (**)writeOption foo.Baz

                                    It's not possible to do that right now and even if I define the function outside at module level (with extra writer parameter), I can't curry it to avoid passing the context (writer) parameter I'm trying to elide to keep my…

                                    1 vote
                                    Vote
                                    Sign in
                                    Check!
                                    (thinking…)
                                    Reset
                                    or sign in with
                                    • facebook
                                    • google
                                      Password icon
                                      I agree to the terms of service
                                      Signed in as (Sign out)
                                      You have left! (?) (thinking…)
                                      1 comment  ·  Admin →
                                    • Add constraints to match FSharpType.Is* predicates

                                      I have a type, CaseSet<'a>, that is only meant to be used with descriminated unions. The only way I've found to enforce this is at runtime using FSharpType.IsUnion. I considered using type providers, but those aren't supported in PCLs.

                                      I propose adding the following constraints based on the corresponding FSharpType reflection functions.

                                      function : IsFunction
                                      tuple : IsTuple
                                      union : IsUnion
                                      record : IsRecord
                                      module : IsModule
                                      exception : IsExceptionRepresentation

                                      (I'm not really sure about that last one... I included it for completeness but maybe just testing for some subclass is sufficient?)

                                      1 vote
                                      Vote
                                      Sign in
                                      Check!
                                      (thinking…)
                                      Reset
                                      or sign in with
                                      • facebook
                                      • google
                                        Password icon
                                        I agree to the terms of service
                                        Signed in as (Sign out)
                                        You have left! (?) (thinking…)
                                      • add a keyword for module-local construction but public deconstruction of types

                                        Similar to dependant types, except you wouldn't enforce the predicate on which the type is dependant on to be defined WITH the type.

                                        This keyword could stop clients of a module from constructing the type, but would allow them to 'see' that it exists, and therefore allow them to deconstruct it for their own use.

                                        For example, if you want a string constrained to 50 chars, you could have

                                        type String50 = constrained String50 of string

                                        let createString50 s = if String.length s <= 50 then Some s else None

                                        where 'createString50' is a constructor.

                                        Correct me if I am…

                                        5 votes
                                        Vote
                                        Sign in
                                        Check!
                                        (thinking…)
                                        Reset
                                        or sign in with
                                        • facebook
                                        • google
                                          Password icon
                                          I agree to the terms of service
                                          Signed in as (Sign out)
                                          You have left! (?) (thinking…)
                                          1 comment  ·  Admin →
                                        • Support partial record prototypes

                                          I have a case where I have several related types (categories of parameter sets for an analytics API). I want to create a set of new types such that every category is required in exactly one of the new types, and all of the other categories are optional.

                                          This is fairly easy to express in a variety of ways in F#, but enforcement becomes difficult. I'd prefer to use record types with a default prototype, but there are no good defaults for the required parameters. I either have to clutter up my types with bona fide classes with constructors, or…

                                          1 vote
                                          Vote
                                          Sign in
                                          Check!
                                          (thinking…)
                                          Reset
                                          or sign in with
                                          • facebook
                                          • google
                                            Password icon
                                            I agree to the terms of service
                                            Signed in as (Sign out)
                                            You have left! (?) (thinking…)

                                          F# Language

                                          Feedback and Knowledge Base