Jack Pappas

My feedback

  1. 10 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…)
      8 comments  ·  F# Language  ·  Admin →
      Jack Pappas commented  · 

      I've implemented these additional intrinsic functions and will be sending a pull request ASAP: https://visualfsharp.codeplex.com/SourceControl/network/forks/jackpappas/fsharpcontrib?branch=native-interop

      Jack Pappas commented  · 

      @Sebastian @FrankNiemeyer I've also suggested 'fixed' be implemented for F# 4.0: https://fslang.uservoice.com/forums/245727-f-language/suggestions/5663721-add-support-for-fixed

      Jack Pappas commented  · 

      One other thing to point out -- having these intrinsics available in normal F# code would make it possible to implement high-speed native interop libraries like SharpDX without having to resort to IL-rewriting: https://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4334135-extend-c-to-close-gaps-for-high-performance-nativ

      Jack Pappas commented  · 

      Will -- nativeptr<'T> is just nativeint with a generic type annotation grafted onto it, and it's erased to nativeint at compile-time. Implementing a cast function like you described should be straightforward if you use the F# proto-compiler. IMO it wouldn't be a good addition to FSharp.Core though, because it would totally bypass any and all type-safety. In any case, the difference between your cast function and the intrinsics I listed above -- you can implement your cast with the current version of F#, but the above intrinsics can't be compiled due to some changes that were made to the ILX layer and metadata picker in F# 3.0.

      Jack Pappas shared this idea  · 
    • 30 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…)
        5 comments  ·  F# Language  ·  Admin →

        Updating to planned to indicate this is approved in general terms. A detailed design and implementation would be needed.

        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.

        Don Syme, F# Language and Core Library Evolution

        Jack Pappas commented  · 

        Another way to implement this (besides what I mentioned below) would be to have a [<ParamDictionary>] attribute and have the F# compiler compile that parameter into an ExpandoObject. That would interop a bit more closely with C# dynamic and the DLR, but the price is that it wouldn't work if targeting a .NET Framework earlier than 4.0.

        Jack Pappas commented  · 

        I don't know about the user-facing side of things (i.e., how to expose this in the language), but on the compiled side of things, you could represent this using the usual [<ParamArray>] attribute with a KeyValuePair<string,obj>[]-typed parameter. That would avoid the need for consuming code to take a dependency on FSharp.Core and it would preserve parameter ordering (as Rick mentioned). Although this doesn't actually use IDictionary<_,_>, it doesn't seem likely that most real-world uses are going to pass in more than, say, 20-30 arguments, so lookups can use a linear scan of the argument array to find a matching k-v pair without too much performance overhead.

      • 311 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…)

          I am generally in favour of addressing this in F# 4.x+. I would want seq { .. } and async { … } tailcalls to also be addressed.

          A more detailed design is needed and some trialling would be great. Jack’s work is a great start. However, this is not an easy piece of work to do in a non-invasive way and my own experiments in this area have not yet led to something I feel confident to include in the F# language design.

          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).

          Currently, initial implementations of approved language design can be submitted as pull requests to the appropriate branch of https://github.com/Microsoft/visualfsharp. See http://fsharp.github.io/2014/06/18/fsharp-contributions.html for info on how to contribute to the F# language/core library design

          I encourage you to consider continue…

          Jack Pappas commented  · 

          I put together a little code sample demonstrating my proposal (see previous comment): https://gist.github.com/jack-pappas/9860949

          To elaborate a bit: the compiler would emit a warning at each call site to a function which shares the same stack frame as the current function -- in other words, when a function is calling itself, or some other function within a group of mutually-recursive functions.

          Jack Pappas commented  · 

          Requiring the compiler to warn you when an entire algorithm is not tail-recursive poses a significant challenge, as Jon and others have pointed out.

          If you relax the definition of this feature request to something like "emit a compiler warning for non-tail-recursive call sites within a 'rec' function", this becomes fairly simple to implement. In addition, you don't need additional keywords or functions to implement this -- it could be a standard compiler warning which is on by default, which means it'd be easy to turn off for those who wanted to do so.

        • 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…)
            4 comments  ·  F# Language  ·  Admin →
            Jack Pappas commented  · 

            Jon -- With try/finally, the code in the finally block is always executed, whether an exception is raised within the protected (try) block or not. With try/fault, the code in the fault block is executed *only* when an exception has been raised in the try block.

            It would be possible to emulate try/fault behavior with try/finally by writing something like this:
            let mutable error = true
            try
            // code which may or may not raise an exception
            error <- false
            finally
            if error then ... // execute the "fault" handler

            but it's hacky and I'd prefer just to use a true 'fault' block (which is already a feature supported by the CLR). In addition, the code to implement try/finally in the compiler is basically identical to what's needed for try/fault, so it should be fairly straightforward to implement this. If this language feature were accepted, I'd be happy to contribute an implementation (or attempt to).

            Jack Pappas shared this idea  · 
          • 23 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 comments  ·  F# Language  ·  Admin →
              Jack Pappas commented  · 

              I have often wished for F# to have this feature. I would be OK if the compiler required active patterns with >7 cases to be inlined -- most of the time I've wanted to use this, the active pattern would only be used in 1 or 2 places in the code, and I've mainly wanted to use an active pattern to take advantage of the exhaustivity checking provided by the compiler.

            • 76 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…)
                Jack Pappas commented  · 

                This is an often-requested feature for F#, usually from people doing heavy mathematical or algorithmic work, and can see how having code which more closely adheres to the underlying math could be helpful.

                However, I have to say -- I don't think it would be good for F# to add this feature. My chief concern is that you'd be forcing consumers of your code to use these symbols as well. This would be annoying at best (I prefer the identifiers as they are now, and would probably end up implementing my own library instead of one that forced me into using Unicode symbols as operators); at worst, code with Unicode operators is much less approachable for newcomers to F# -- especially those who don't come from a math/science-heavy background -- and I worry it would keep people away from F# who might otherwise be quite happy with the language.

                Another drawback -- a number of mainstream development tools (including parts of VS) weren't designed with Unicode symbols in mind, and won't work properly when code or compiled assemblies use them in type/field/method names. You can make a good argument that these tools should be fixed to properly handle Unicode symbols (and I would agree with you); but if having Unicode operators means that many of the common .NET development tools couldn't be used with F# due to such issues, I think that would be a serious problem. Even well-known C# libraries have removed the uses of Unicode characters from their method names due to this issue: http://rx.codeplex.com/releases/view/114891

                What's the downside of having an IDE plugin (like F# Power Tools), or the add-on Daniel linked to, that could recognize naming conventions for variables and convert them to Unicode characters in the IDE (but not in the actual code)? Proof General (an Emacs package) does this for Isar (a proof language for the Isabelle theorem prover) and it seems to work quite well: http://proofgeneral.inf.ed.ac.uk/releases/ProofGeneral-3.7/isar/isar-unicode-tokens.el

              • 92 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…)
                  Jack Pappas commented  · 

                  Daniel -- no, object expressions don't face the same problems, because they're only required to implement the interface. The problems with these proposed extension interfaces is that they need to have a type which matches both the class being extended and the interface(s) being added. This is the reason it's impossible for this to work with sealed classes and value types, or unsealed classes which have internal/protected constructors.

                  The only way I can think for this to work (unless I've misinterpreted Ryan's intentions) is that by extending existing types with these new interfaces, you'd basically just be making a shortcut for using object expressions somewhere else in your code. In other words, the compiler would not actually create a new type derived from the type being extended and the interfaces, but would in fact create a static method (in some module) which takes an instance of the type being extended and internally uses an object expression to produce an instance of the interface which was "added" to the type. It would then need to insert a call to this method into any call sites where instances of the interface were expected and you'd passed an instance of the type being extended.

                  Jack Pappas commented  · 

                  This is an interesting idea, and I can think of some times in the past where it would have been useful.

                  I could be mistaken, but after thinking it over a bit, it seems like this could only work for non-sealed classes; trying to extend sealed classes or value types would lead to issues when interoperating with non-F# code. Extending base classes or interfaces seems possible but very tricky to get right. For example, if you extended a base class which has some derived types, the F# compiler would have to create backing classes (in the compiled assembly) for the base class and any of the derived classes you used in your F# code, just to make sure the 'derives-from' and 'implements' relationships still hold correctly from the POV of any outside code.

                • 133 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…)
                    Jack Pappas commented  · 

                    @Mastr Mastic Admittedly, I do very little GUI programming, so I haven't run into the situation you described. The additional explanation you added makes a lot of sense, and I think you've made some good arguments for why this feature *should* be implemented. This would be a big change to the language though, and might also pose some challenges w.r.t. to type inference, so the more examples you can provide where the current behavior (explicit interface implementations only) is holding you back, the better.

                    Jack Pappas commented  · 

                    I personally prefer the requirement for explicit interface implementation and would like to continue to enforce that requirement in my own codebase, so if this feature were implemented I would like to have a compiler option to disable it (or perhaps, it should be disabled by default and activated by a compiler flag).

                  • 248 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…)
                      under review  ·  8 comments  ·  F# Language  ·  Admin →
                      Jack Pappas shared this idea  · 
                    • 150 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…)
                        under review  ·  9 comments  ·  F# Language  ·  Admin →
                        Jack Pappas commented  · 

                        This would be a nice feature to have. Even if it were infrequently used in F#-only code, it would be very handy to have when implementing libraries to be consumed from C#.

                        BTW, F# already does support a bit of contravariance via "flexible types". Flexible types don't seem to be used very often except with the 'seq<_>' type; if co-/contra-variance are properly supported in F# (a la C# 4.0), flexible types could be deprecated in favor of the variance annotations.

                        If this feature is implemented, I'd prefer it use the C#-style "in" and "out" keywords instead of OCaml's +/- syntax; I think the keywords are easier to read, they'll stand out when highlighted in an IDE, and it'll make it easier for C# developers to learn F# (or at least, they'll be able to re-use existing knowledge about the in/out keywords).

                      • 98 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…)
                          5 comments  ·  F# Language  ·  Admin →
                          Jack Pappas supported this idea  · 
                          Jack Pappas commented  · 

                          This is one feature I'd really like to see in F#, and it seems like it should be very simple to implement. If the 'protected' modifier was omitted from the language to nudge developers away from OO-style code, I think that may have been the wrong way to go about it, because it makes it impossible to re-implement OO-heavy C# projects in F# in such a way that the change is transparent to any consumers. Consequently, I've had to pass on using F# to replace some C# projects -- the downside of having to re-architect large parts of an existing codebase because F# classes can't declare 'protected' members is very often going to outweigh any upsides that could be had from re-implementing a single project in F#.

                        • 111 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 comments  ·  F# Language  ·  Admin →

                            Marking as “approved in principle” (it will show as “planned”).

                            However, in reality it is both relatively low priority and relatively hard to implement, so I don’t expect this to happen any time soon.

                            For example, we would have to reverse-map the metadata associated with F#-specific types. This is already done in F# reflection FSharpType.IsRecord and so on.

                            Jack Pappas commented  · 

                            What limits you from generating DUs and Records in type providers now? Is the limitation in the F# compiler itself, or in the ubiquitous ProvidedTypes.fs? If it's the latter, this feature could be implemented through a community effort.

                          • 131 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…)
                              Jack Pappas commented  · 

                              OCaml does have this, so it is possible -- but as Jon H. pointed out, it's very easy to make this feature "too powerful" and ultimately cause more problems than it solves.

                              +1 for Jon's suggestion that if this were implemented, it should only be for let-bound functions using the tupled argument style. I think that would provide a good compromise because you'd be able to write let-bound functions in modules in exactly the same way you're writing methods in static classes now (sans overloading), without introducing the complexity of optional curried arguments or type inference when using named arguments.

                            Feedback and Knowledge Base