Settings

Theme

Get Started with F# as a C# developer

blogs.msdn.microsoft.com

70 points by edgyswingset 8 years ago · 59 comments

Reader

GiorgioG 8 years ago

I'll take MS's commitment to F# seriously when they stop treating it like a 2nd class citizen. .NET Core 1.0 has been out for over a year, .NET Core 2.0 is in preview and there is ZERO support for F# with .NET Core in Visual Studio 2017. Yes you can use VSCode, but VSCode is no Visual Studio - it's a text editor on steroids, not a proper IDE that most C# developers have come to expect.

  • louthy 8 years ago

    I agree, it's been a nightmare. I've dropped support for F# from my FOSS project because I can't get the .NET Core build working alongside the C# projects (and packed in a nu-get package, and deployed all in one process). I know that if I try to use it alongside any C# projects I will almost certainly lose many hours of time and it probably will fail to work at all.

    I don't know how much of this is the F# team's fault, but F# the 'eco-system' feels like it's going backwards at the moment.

    • kirse 8 years ago

      F# the 'eco-system' feels like it's going backwards at the moment.

      As in physics, it's all relative. .NET has been moving so quickly lately that the F# team (from my outside-looking-in view) does not have the resources to keep up. You can see that by how stretched thin they are on GitHub issues. I'd imagine things will eventually stabilize once .NET Core settles in, but that'll be a few years.

      But you are right, the tradeoff always seems to be "do I want to struggle and learn" or "do I just want to get things done."

      • GiorgioG 8 years ago

        If you want to get things done in .NET Core, use C#. If you want to learn functional programming then sure, use F# and the full .NET Framework...but good luck finding help when you need it because compared to the number of people Elixir, Scala, etc - hardly anyone is using F#.

        I started learning F#, but ultimately I decided I'd rather learn either Scala or Elixir because they are more "mainstream" functional programming options. If anyone doubts this, compare the number of F# repos to Elixir/Scala on Github.

        I've voiced my frustration on several Github issues about the fact that F# is understaffed at MS, that F# is a 2nd class citizen to C#, etc - to no avail. It's fine, management at MS makes those calls...but then they shouldn't be surprised that there's no uptake on F#'s usage.

        • wyoung2 8 years ago

          > If you want to get things done in .NET Core, use C#.

          And if you want to get things done in F#, don't use .NET Core. :) Good thing .NET Core is merely the .NET du jour, not the only .NET.

          > If anyone doubts this, compare the number of F# repos to Elixir/Scala on Github.

          Challenge accepted. It turns out that GitHub's advanced search page can answer questions like this directly:

          Projects written in F#: 4,246 (https://github.com/search?utf8=%E2%9C%93&q=language%3AF%23&t...)

          Projects written in Elixir: 4,667 (https://github.com/search?utf8=%E2%9C%93&q=language%3AElixir...)

          That's less than 10% higher. Plus, I'd guess there is a bias against closed-source projects in that result, owing to the nature of .NET.

          Scala is indeed a lot higher at 38,424 projects, though I wonder how many of the complaints about F# from C# users apply apply equally to Scala. (e.g. Poor GUI builder support, no native compiler, etc.)

          F#'s language representation on GitHub is also nearly equal to that of OCaml, a much older language.

          I'd say that's a pretty good showing for a new-ish language. Not everything's going to pop to the top like Swift, which IMHO is a "people in Hell want ice water" reaction to Objectionable C.

          • GiorgioG 8 years ago

            > And if you want to get things done in F#, don't use .NET Core. :)

            Yep - stick with the version of .NET that MS is desperately trying to deprecate - remember recently when they tried to get away with not supporting ASP.NET Core 2.0 on the full framework?

            > Good thing .NET Core is merely the .NET du jour, not the only .NET.

            Yep, who would want to use the cross-platform, modern implementation of .NET?

            > That's less than 10% higher.

            Except that F# has been around twice as long as Elixir (2005 vs 2011.)

            F# is the minor league team that C# farms features from. Nothing more in microsoft’s eyes.

  • wyoung2 8 years ago

    > I'll take MS's commitment to F# seriously when they stop treating it like a 2nd class citizen.

    If you're waiting for Microsoft to give exactly equal resources to both C# and F#, you'll be waiting forever. Just like you'll be waiting for equal resources given to Visual Basic, TypeScript, PowerShell, VBA...

    Equal splits never happen in a competitive situation. 60/40 splits are much more common, but here in this case, we have many first-party languages, so you'd expect a more complicated split, just as we see now.

    > .NET Core 2.0 is in preview and there is ZERO support for F# with .NET Core in Visual Studio 2017

    That's coming in the next update. (https://blogs.msdn.microsoft.com/visualstudio/2017/05/10/upd...) You've been able to run F# in .NET Core in preview form going back to the 1.1 series.

    My opinion is that .NET Core is the real bag of hurt here, not F#. Stop sticking your hand in that blender. Use Mono and open source F# until .NET Core stops changing the world on each release.

    > VSCode is no Visual Studio

    And neither one is Vim.

    Are we really going to have another editor war? :)

  • arwhatever 8 years ago

    It will be a big screw-up if MS introduces such a fabulous language and then doesn't support it adequately, because now that I have seen the light, if their support becomes too scant I will drop .NET/core like a hot potato and will find some other comparable language in whatever other framework and environment I need to transition to.

  • pjmlp 8 years ago

    Not only that, there is zero support for UWP and .NET Native.

nlawalker 8 years ago

Can anyone suggest any F# tutorials in the style of Michael Hartl's Rails Tutorial?

F# suffers from an overabundance of "getting started" tutorials that focus only on the language and syntax. I get that F# is likely to be a lot of peoples' first introduction to a functional language, so that makes sense, but this one doesn't even tell you how to run the code it's showing you.

The hardest part about learning any new language isn't learning the syntax or core concepts, it's understanding the mechanics of actually getting things done - grokking the developer workflow, getting comfortable in an editing environment, building and deploying, troubleshooting and debugging, writing idiomatic code, learning about common libraries and tools, etc.

hdhzy 8 years ago

Are there any simple projects like HTTP server in F# for CoreCLR somewhere? With a Dockerfile if possible. Last time I tried to build something like that for PoC the amount of struggles I had with various versions of CoreCLR was overwhelming.

NicoJuicy 8 years ago

If you want to try out f#, don't forget to try it with http://fsharp.github.io/FSharp.Data/

It's pretty awesome

stinos 8 years ago

Ask HN: I've toyed around with F# and I kinda like it but I've never dug deep enough into it to answer the question: can I use this for 'real life' code as part of an existing C# desktop application for instance, e.g. build some F# into an assembly which is callable from C#? Without tons of hassle? What are good samples of real life application code in F#?

  • talyian 8 years ago

    > can I use this for 'real life' code as part of an existing C# desktop application .. without tons of hassle

    Yes. Your standard OOP features like inheriting from C# classes, implementing interfaces, etc are supported natively in F#. The main hassle in being C#-compatible is exposing an external OOP api with only .NET types and interfaces instead of standard F# types. This means, for example, exposing `seq` (`IEnumerable`) instead of `list` (`Microsoft.FSharp.Collections.List`) or using the struct-tuple construct in F# 4.1 so C# 7 can access it.

    > good samples of real life application code

    No personal recommendations but have you seen https://github.com/fsprojects/awesome-fsharp

  • eurg 8 years ago

    > Without tons of hassle?

    Well, yes and no. You definitely can do this, and for some applications it's worth it, but often the overhead at the API level will make you cringe.

    APIs designed for C# are very different than APIs designed for F#, to account for partial application of functions, sum-types, non-nullability, immutability and value-like behavior by default from F# types, and also to make good use of F#'s type inference. Also, given stuff like the |> operator, making "fluent" APIs looks very different.

    Using APIs made explictly for F# from the side of C# is somewhere between enormously annoying and de-facto impossible. The other way 'round, it's just massively annoying, as you lose many advantages of F#, and the code will not be much more compact as if you would write it from C#.

    Pain-points in practice are around F# functions vs. C# methods and delegates, async/await vs. async-expressions, code quotations vs. Linq expressions, etc.

    To be productive in F#, you want your API small and primitive, and stay within the language for the rest. If this is possible, go for it; if not, evaluate.

    A final tip: Porting a big block from C# to F# is much less work than it sounds, and opens the door to refactoring that part into something sensible.

    • maxxxxx 8 years ago

      Are there any F# APIs? I tried to introduce F# to a project but between all needed APIs written in C#/OOP style and only mild interest from a lot of developers and managers I couldn't really justify the added friction.

      If there were a ton of F# libraries that showed how to create functional APIs people could learn from them by using them the same way a lot people learn OOP by using APIs.

      As it is now the only way to get into F# is to have a group who really wants to do it and learn. Otherwise it's just an uphill battle.

  • angrydexterous 8 years ago

    Absolutely Here's some nice slices

    Starting with front-end since it's a bit easier to jump into

    Back-End C#, front-end SPA in F#

    Check out Fable-Elmish (and Fable-Elmish with React (Elm-style model-update-view for React)) https://github.com/fable-elmish/elmish

    WPF Desktop -> Elmish.WPF (Elm-style model-update-view for WPF) Check-out https://github.com/Prolucid/Elmish.WPF

    Back-End Slices for lambda-architecture-style systems

    Web,Front-end in whatever, streaming with Storm and F# via FsShelter (and FsCassy for Cassandra, FsBunny for RabbitMQ)

    Streaming, front-end in whatever, Web Layer with Freya

    Also: Some tips Install VS Code with all the ionide plugins. Also grab Forge to create new fsharp projects if you're not doing net core development. Use Expecto for tests. Then from the editor you can build,run, debug, paket install, and run test(s)

  • jackmott 8 years ago

    yes you can. C# / F# interop is not zero hassle but it is low hassle. Most of the time it just works. There are a few features in each language that are not zero hassle, if a C# api uses a custom implicit conversion, calling it from F# requires you to explicitly call the implicit conversion (ha!) and if an F# api returns something F# specific like an Option type, using it in c# can be a pain.

    At my company we have a C# codebase for a large web application, but we create a 2 stage caching feature for it in F#. This F# project uses a couple of C# oriented libraries (stackexchange.redis and protobuf-net). So lots of interop going both ways.

    Some examples of people using it in production: http://fsharp.org/testimonials/

  • stinos 8 years ago

    I'm not gonna say thanks to each post individually, so: thanks for all replies! Really informative.

  • louthy 8 years ago

    It depends, if you want to use it side-by-side with C# in a .NET Core project I'd say "forget it", you will just come away with scars from the process. If you're doing a greenfield F# only project, yeah sure, it all works lovely and is a great language.

  • wyoung2 8 years ago

    I can't share the code with you, but I did just that on a proprietary app for my company. Only the GUI shell of the app is in C#, and that only because the GUI builder features of Visual Studio can only generate C# code.

    All of the "real" code in that app is in an F# library, which you add to the Visual Studio solution just like you would any other C# helper library. When you add a source file to that library, it's an F# source file, and it's built with the F# compiler into the library, which is then linked with the C# "main" program.

    There are a few tricky parts, owing to the substantial differences between C# and F#. They all come down to the fact that there are aspects of both C# and F# that don't map naturally to the other. While there may be low-level .NET or IL ways to force the call, it's better to restrict your use of each language at the boundary between the two parts of the program.

    Some examples:

    1. F# has two ways of passing parameters to a function called the tuple and curry forms. Curried functions are the full-power form, but C# can't call them directly, so any function or method you want to export to the C# side must use the tuple form. At a superficial level, the only difference is some parentheses and commas, but at a low level, you're purposely nerfing the F# function to allow C# to call it. This is not an area you can avoid knowing about, since all of .NET uses tupled calling form, being written for C# initially.

    2. F# has several native data types that have no direct implementation in C#. Some newer versions of C# have .NET extensions to allow them to manipulate values of these types given to the C# side from the F# side, but given a choice, it's often simpler to restrict the set of data types you define the interface between the two in terms of. That is, you generally don't want to allow discriminated unions, records, tuples, or function values through the boundary, if you can help it. Use data types C# copes with better: classes, structures, lists, and arrays instead.

    3. C# code often makes use of null values, which are...well, "sinful" in F#. It is possible to use null in F#, but strongly recommended against, since F# is all about definite value states, and null adds an element of indefinite-ness to the application. You can choose either to allow null values through the C# to F# boundary or enforce the F# side's wish not to accept them at the boundary. Your choice.

    4. Once you get into the F# way of doing things, you start to become more choosy about the C# libraries you use from F#, since some are more acceptable from an F# standpoint than others. You start to avoid libraries that have mutable values flying around everywhere, methods with side effects, etc. Some C# libraries are outright annoying to use, because you have to continually cast away so much of the F# value in order to use them. Fortunately, .NET itself is generally pretty good in this regard. The NuGet world shows less restraint here.

    • maxxxxx 8 years ago

      Were your fellow developers interested in F#? I have found most people simply don't care and don't want to learn it.

      And there is the famous line "Functional programming? We did functions 30 years ago. No big deal".

      • wyoung2 8 years ago

        > Were your fellow developers interested in F#?

        I was sole developer on that project.

        But here's a thought for you: you can only achieve mediocrity if all choices require 100% buy-in from all interested parties.

        > I have found most people simply don't care and don't want to learn it.

        No one likes to have their cheese moved. But cheese moves nevertheless.

        > We did functions 30 years ago.

        Most people saying that probably don't realize that what computer programmers call "functions" are not what mathematicians call "functions."

        The reason FP is becoming popular now is that the distinction now matters much more than ever in today's multicore world, where multiprocessing is often the only practical way to make software substantially faster.

        • maxxxxx 8 years ago

          'But here's a thought for you: you can only achieve mediocrity if all choices require 100% buy-in from all interested parties."

          Exactly! Unfortunately this is the reality in a lot of corporations. Pretty sad.

  • pjmlp 8 years ago

    Beware that you won't be able to deploy the code to UWP though.

    • et1975 8 years ago

      There is a way to develop for UWP with F# - MS' own React Native support + Fable. Write your app in F# using Fable React Native bindings, transpile to JS and deploy to UWP.

debacle 8 years ago

I need to know why to use F#, not how. C# is a business programming language. F# doesn't appear to be obviously useful in that regard.

  • steego 8 years ago

    I would argue that F# is a better business programming language for a lot of reasons.

    First, the type system is great when it comes to modeling the problem and communicating that model with non-technical project managers because writing good data models often means you write clear code that's idiosyncratic to the language. My experience is non-technical people understand clear data models and pipelines and those are two areas where F# code reads very clearly.

    If OOP is your thing, I can argue it's a much better OOP language than C#. From a SOLID and Design Patterns perspective, the language has been streamlined to encourage a good OOP style by default. Design Patterns are simpler (Factory, Builder, Decorator, Adaptor, etc). Dependency Injection is very natural and implementing fluent APIs is a lot simpler.

    The biggest benefits come from maintaining good hygiene. You're a lot less likely to have null reference exceptions or introduce invalid states. Race conditions are harder when most things are immutable by default. You're also less likely to encode things poorly because your type system sucks. You'll think more carefully about how you write loops, ifs and switch statements because the compiler catches and prevents you from doing boneheaded things. It's also has features that prevent you from accidentally adding cyclomatic complexity. For example, lower-level modules are not allowed to refer to higher-level modules. It's also harder to accidentally make functions recursive because it requires a special "rec" keyword.

    I realize people dismiss hygiene, but this stuff really goes a long way to help manage complexity when it comes to growing and maintaining applications over long periods of time.

    I'm not going to claim it's great at everything. It's a wonderful back-end and business language, and it's fantastic at modeling business objects and records. However, the tooling isn't there for doing WPF applications. Also, sometimes you come across issues with libraries that work well with C# defaults but not F# defaults. For example, F# properties tend to be read-only by default, so libraries that hydrate objects with data don't work unless you explicitly make those properties writable.

    Nevertheless, if nothing else was an issue (buy in, training, etc), I'd opt to write the business logic in F# 9 times out of 10 times and save C# for the front-end (tooling).

    • nlawalker 8 years ago

      >> the language has been streamlined to encourage a good OOP style by default. Design Patterns are simpler (Factory, Builder, Decorator, Adaptor, etc). Dependency Injection is very natural and implementing fluent APIs is a lot simpler.

      Can you expand on this? I'm interested in how these things are easier in F# than in C#.

  • addicted 8 years ago

    The first sentence in that post.

    "One of our previous posts, Why You Should Use F#, listed a few reasons why F# is worth trying out today"

    I would argue F# is a much better business programming language than C#. Admittedly, I am not very good at it, and have barely done more than a few toy programs in it, but F# (like most FP languages) allows you to bake in a lot of the rules into the Types themselves, and immutability combined with a lack of nullness protects you from a lot of footguns.

  • KurtMueller 8 years ago

    Scott Wlaschin's talk does a pretty good job of demonstrating how F# is pretty great for BLOBAs (Boring Line of Business applications).

    You can find it here: https://fsharpforfunandprofit.com/ddd/

oxryly1 8 years ago

Asynchronous programming with F# is pretty cool. It has layered powerful syntax and language constructs on top of .NET's threads and tasks, AND it gives you convenient access to the same async API that you use in C#.

  • GordonS 8 years ago

    I'm a C# dev and recently tried out F#. Async and async workflows/computation expressions were actually one of the things I struggled most with in F#. Can you suggest any good resources for learning more?

  • jackmott 8 years ago

    performance is not good though, if you are trying to use it to leverage multiple cores.

    • oxryly1 8 years ago

      Is this because of GC? I just came across this statement on the Hopac site:

      > Before you begin using Hopac, make sure that you have configured your F# interactive and your application to use server garbage collection. By default, .Net uses single-threaded workstation garbage collection, which makes it impossible for parallel programs to scale.

marvel_boy 8 years ago

Newbie here. Somebody can point to useful other resources for F#?

  • oxryly1 8 years ago

    https://fsharpforfunandprofit.com is great. I'm enjoying Don Syme's book "Expert F# 4.0" as well.

    • JamesBarney 8 years ago

      This website if one of the best I've read, and I recommend it even if you have no interest in F#. I learned more about how to write OOP and think about types than years of reading other blogs.

  • rspeele 8 years ago

    If you are a C# developer you may appreciate these translations I've put together:

    https://github.com/rspeele/CSharpFSharpPhrasebook

    This does not sell the language -- it doesn't show off anything interesting you can do in F# that you can't in C#. There are other resources for "why F#". This is for C# developers who are convinced that they want to learn, but are annoyed by not being able to quickly look up how to do the things that they're familiar with from C#.

  • voqk 8 years ago
  • eddof13 8 years ago

    Seconding the f# for fun and profit suggestions, especially the railway oriented programming section, I've also heard the following is good, but I have yet to try them:

    http://www.fsharpworkshop.com/ http://products.tamizhvendan.in/fsharp-applied/

  • kzisme 8 years ago

    Is there a really good reason to choose to use F# over C#? Or does it really just come down to preference?

    • sremani 8 years ago

      The returns on choosing F# are very much reliant of level of proficiency attained.

      Once you are proficient, you will write

      - less code for similar functionality

      - have lot less dependency cycles

      - using Option types over null helps in the long run

      - improvement in productivity

      The only problem is that you have attain a level of proficiency and flip the "train" of thought from OOP to Functional, and that can take some good time.

      • kzisme 8 years ago

        Gotcha - thanks! I haven't touched functional languages other than for fun lately, so I may take a look sooner or later. I've always been interested.

    • wyoung2 8 years ago

      Just to add to what the others have said:

      1. Immutable values by default avoids whole categories of problems. Just for one example, you can't have a data race between two threads if all the public values accessible from each thread are guaranteed immutable.

      2. F# forces all cases to be handled. You've doubtless run into C# code that has a switch statement that doesn't have cases for all possible inputs, and no default case. F# doesn't have a direct equivalent of "switch" at all, but it does enforce completeness in the equivalents it does have. For example, it's illegal in F# to say something like "if foo > 1 then ... elif foo < 1 ..." since that leaves the 0 case unhandled. This is not just about better compiler warnings: it's required by the very fact that "if/else" is an expression, not a statement, so all branches must produce a value for all inputs.

      3. F# has units of measure data types. Ever had an application bug because you've incorrectly passed a bare "int" value holding milliseconds to a function expecting seconds? I have. F# lets you define your units as part of the data type, so that it's a compiler error to pass milliseconds to a function expecting seconds.

      I could go on, but as you can see, there really are substantial differences in practice between F# and C# code.

    • jackmott 8 years ago

      pros: less typing less null pointer exceptions

      cons: performance (doesn't have to be bad but if you do things idiomatically will tend to be) tooling and other externalities (better that most niche languages but not as good as c#)

    • mookid11 8 years ago

      It depends if you enjoy NullPointerExceptions.

nullspace 8 years ago

  // Flip the BST using pattern matching!
  let rec flip bst =
    match bst with
    | Empty -> bst
    | Node(item, left, right) -> Node(item, flip right, flip left)

Without type annotations, how can it tell the flip takes an instance of BST as the parameter?
  • omaranto 8 years ago

    The variable bst is something that can be matched with Empty and with Node(item, left, right), both of which are of type BST. When two values can be matched with each other, they must be of the same type. Therefore bst is of type BST too.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection