Who better to ask about F# than someone who has dedicated an extensive website to the language? Scott Vlasheen has created a resource «F# for Fun and Profit» , familiar to many Habravchans : on Habra, translated from there and series of articles "Functional Thinking, " and article "Railroad-oriented Programming."
And in November he will speak in Moscow at our DotNext conference with reports "The power of composition." And ahead of this talk we asked him about F# and functional programming in general.
– Let’s go from the beginning : what did you do before functional programming, how did you come to F# and how did you create the site?
– I am a person of a respectable age, and when I went to university, there were no separate programs in computer science yet. I had a mathematical education, but I did not want to do mathematics, so after university I worked for about 10 years in a variety of jobs, including a carpenter.
One day in the late 1980s my dad bought a computer for his work, a CP/M Kaypro, with a paltry amount of memory and 5.25" floppy disks. This was before Windows even existed, so it had DOS on it. That’s where I started programming. I was doing databases, at first for my father, he needed it for his work. And then I started doing it professionally.
My first language was Turbo Pascal, and in 1989 or 1990 I was introduced to Smalltalk, and I liked it a lot, it’s still one of my favorite languages. One job followed another, and eventually I, like most programmers, got a job at a big company writing boring business applications (I call them "BLOBs": Boring Line-of-Business applications). And for a very long time, that’s all I did.
I’ve been writing in Python for a while, and in C# for about 10 years. And in 2011, that is, not so long ago, I decided that I was bored with my job and it would be good to try something new; so I wanted to get into functional programming. It turned out that I already had a functional language in my Visual Studio, so I tried F#. And at first it seemed very strange, I couldn’t understand anything, it was so different from anything I had worked with before.
There were some good blogs about F# but very few of them, and not much documentation either. In the end, my friends gave me great advice: if you want to learn something, try to start teaching it to others, because it makes you understand the subject very well. They also advised me to start a blog because it makes me stand out among the other programmers.
So, in 2012 I started a blog "F# for fun and profit" and started to publish there articles every time I learned something new about F#. Now it has several hundreds of pages and has become very popular. At first it was just a hobby, I was doing it in my spare time. And then about 3 or 4 years ago, I decided to quit my job and become a freelance consultant. The year before that, I wrote a book, which also turned out to be quite popular. That’s how my introduction to F# came about.
– As a freelancer, do you work specifically with F#, or not only?
– Mostly F#, but generally speaking, I consult on what I get paid for *♪ Laughs ♪ If I need money, and someone has a C# job, and it looks interesting, I’ll take it. And last year I worked with Python for three months. It’s not the language that’s more important to me, it’s what kind of problem you have to solve. I like to learn, and when you’re hired to solve a problem, you have to become if not an expert, at least understand some new area.
I had to study real estate economics and insurance risks this way. I think you can only write good code when you understand the subject you’re dealing with well, not just writing what others tell you. For me that’s the most interesting part – not the language, but the problem.
– In Russia, although some developers are interested in F#, it is hard for business with this language: it is harder to find or replace a developer than with C#. And the companies you work with, how do you decide to use F#?
– There are two most common situations here. The first one is when a company is already using F#, they usually have some kind of experimental project. They call me and ask me to help them get that project up and running and teach them the language. They’re usually willing to spend about six months on such a project to figure out if they want to pursue it further.
In addition to that, I teach people domain-driven design, and F# is not the focus here, but I use it as a language. I show to programmers used to C# how much shorter the same code can be in F# than in C#. So I’m quietly promoting the language. It helps that you don’t have to use F# all together, you can write a domain model in F# and do the rest in C#.
– You say that C# and F# can be used together. But in C# enterprising, Entity Framework, NHibernate or something similar is most often used. And among F# developers it’s much less popular. How to mix these languages taking into account the difference in approaches?
– One of the companies I worked with was using the Entity Framework. They were trying to move to a Ports and Adapters architecture, which is to take all the I/O out of the core architecture. Entity Framework is pretty poorly suited for that. In these situations, it’s much more convenient to use something like Dapper, which allows you to not have to deal with SQL in the middle of your code. Among other things, it simplifies testing.
Even though they don’t use functional programming, the situation still pushes them to have a pure core program and keep the database somewhere on the periphery. If the mindset has shifted to this format, it’s already an important step in the direction of abandoning Entity. In a company like that, I really wouldn’t change anything anymore. You can’t force people to change, they have to want to change themselves. I’m not trying to sell myself and impose what I think is the best way for someone to change. Usually people already want to change, and I just help them to do that. You know what I mean?
– So your customers are companies that are already transitioning to a more functional approach themselves.
– Even if they’re working with C#, they’re moving to more functional C#, starting to use LINQ, immutable data structures, that is generally going in that direction. So for them to switch to F# is no longer a big leap.
Are the professions of a developer and a carpenter similar?
– You have an interesting thread on Twitter comparing the work of a programmer and a carpenter. I’d like to ask about "functionality" from that thread. But can you start by retelling the gist of it for our readers?
– Developers like to compare themselves to engineers, and software development to building buildings or bridges. And there is a lot of debate about whether programming is really close to these activities, or if they are fundamentally different. Like, our project requirements change every day – when you’re building a bridge, it’s probably not like that at all? Or is it really like that there, too?
I, on the other hand, believe that there is no one right answer in this argument. I have never been an engineer, but I have been a carpenter. And I can tell you that carpenters have many different jobs, very different formats, and each requires a different approach.
For example, on one job I did kitchen cabinets. In America, they are all very much standardized, all the same size, fit together, and the work is done with power tools. Some quality must be ensured, but in America an old kitchen is usually thrown away when the house changes owners, which means it won’t last very long. So this kind of work is all about speed and saving money.
Then I had another assignment where I had to replace a large, 6-inch oak beam in the middle of a room in a building that was 400-500 years old. Here it was the opposite: everything was curved, no right angles, and to replace it, you had to hand-fit the new piece of wood so that it was exactly the same shape as the old one. This required a great deal of care.
Finally, there was a third job where I made stage sets. They were made of plywood and very thin wood for supports.
My point is that every job requires a different approach. In the case of kitchen cabinets, you need precision, use of power tools, and reproducibility of results. In an old wooden house you are working with a legacy system, it’s important to be accurate, not to rush, it’s not about speed but about getting the result right. Finally, with the decorations you are deliberately creating a fragile structure that is not supposed to be strong, often you have to saw it up and put it back together again in minutes, it doesn’t last forever.
When they say that programming is like engineering, this is only true for some types of programming. For example, if you’re writing software that controls an airplane, you have to be very accurate and very precise. It’s quite another thing to write a one-line script to search for files, it’s more like creating scenery. There is no point in spending 20 hours to prove that this script works and writing 1000 unit tests for it. The whole job should take no more than 5 minutes. And when you are working with a legacy system you must maximally adapt your code to the already existing one, large refactorings are not desirable here.
So in each case, the context is important. Sometimes you have to plan a lot, think a lot about a project, write a lot of tests. Other times, it’s enough to do something in a hurry. Many people lack flexibility in this regard, they think that if you don’t use unit tests or don’t use some programming language, you’re not a professional. Actually, the idea that everything depends on context is pretty obvious. What is rather surprising is how stubbornly some programmers insist on their ideas, and if you deviate from their ideals in any way, you are immediately blacklisted. I think that’s stupid.
– You say that to the outside observer the activity looks the same, but when you see it from the inside, you find completely different cases. And you have to ask: is it the same with functional programming? Those who look from the outside have a common stereotype, but in fact there are gigantic differences?
– Quite right. From the outside it may seem that all "functionalists" think alike, but there are many different groups out there that argue with each other: supporters of Haskell, F#, Clojure, Elm. Even within F# there is a strong disagreement about the direction the language should take, whether it should try to emulate Haskell or whether the priority should be ease of use. So you’re right, inside this field is much more diverse than it is usually presented by outsiders.
– For the differences in carpenter’s work, you gave very illustrative examples. Can you illustrate the differences in functional programming with concrete examples, too?
– There is a school of functional programming that believes in trying to prove everything, and for everything to be mathematically perfect. This school uses a lot of mathematical jargon, such as "monoids" or "monads". It’s mostly Haskell users, and there’s a lot of academic influence here.
And then there are the people who are more concerned with getting results. They are not so much interested in math as they are in immutability and taking I/O to the periphery. The best example of this approach is the Elm community. They are primarily concerned with building web applications. As opposed to the first group, they deliberately avoid using mathematical jargon, and deliberately give up some functionality that is in Haskell and that Haskell users find vital.
Besides, there is an argument between supporters of strong typing and dynamic typing. The average person thinks of functional programming as something like Haskell or F#, but beyond that there are languages like Clojure which have dynamic typing and a very different approach to solving problems. If you get all this motley bunch in one room, they might fight. I, on the other hand, believe that all approaches have their rationale, and when I work for someone, I don’t tell them that their approach is wrong.
– Many people are scared off by the mentioned "academicism" ("F# is rooted in ML, which is for rigorous scientific proofs, and I am solving real problems here"). But, it turns out, people are afraid for nothing?
– It seems strange to me in general that so many people are used to thinking of academia as something negative. I mean, like, some people see it as negative, others see it as positive.
The fact is that many of the techniques that we now use in programming originated in an academic environment, such as garbage collection or types. So there’s nothing wrong with academic techniques in and of themselves. The other issue is that too much emphasis on them can be harmful, because academics and programmers have different goals.
Although functional languages have academic roots, it seems to me a good decision to deliberately hide this logic in languages like F# and Elm. That’s why F# is not used to prove theorems, but to solve real-world problems, it’s a very pragmatic language. And universities have now moved to even more complex languages, such as Coq, F* and the like. They are much more academic, and are used to prove theorems.
As I said, scientists and programmers do different things. Programmers spend most of their time reading and writing files, working with databases, displaying data on the screen, checking data entered, converting data, and so on. And scientists are not interested in such things. But the thing is, things that were purely academic 40 years ago may not be so today.
– As you yourself said in connection with carpenter work, different approaches are good in different contexts, there are no universal ones. And specifically F# is also best suited to certain tasks. What are those tasks?
– Yes, it’s definitely not a universal language, I certainly wouldn’t recommend it to everyone in general, that would be silly. But I think F# is a great replacement for C#, except for really high performance tasks. F# programming is based on a totally different approach: immutability, structural equality, explicit dependencies, no null values in F#, and so on. And it seems to me that this approach is much more useful for everyday programming tasks.
So if one is using C#, one should definitely look into F#, this language would help make the code better. As for other uses, I think F# would be a good fit for many of the tasks that Python is currently used for. F# and Python are very similar, and I think F# has great potential for data processing. It’s an area that still needs work for now, but maybe in a few years people will be using F# for various things related to big data and data science that Python is used for now.
– As you pointed out in your talk "F# for C# developers", it’s not the syntax but the philosophy of the language that matters. But here lies the difficulty for those who want to quickly find out "if this language is good for me". One can already know if one likes the syntax from a cursory acquaintance. But how long does it take to understand the philosophy of a language?
– A person who writes in C# can figure out a language like Java or Go pretty quickly, because most of these standard languages have roughly the same imperative model. Going from them to F# definitely takes a lot of effort, and that stops some people. In my experience, F# is much easier to learn if you forget everything you know about OOP for a while. Otherwise, you start carrying stuff from C# into F#.
As for time, after about two weeks of learning you can already start writing working code, and it will take a few more months to get more or less familiar with the language. Finally, for a good level you need more time, 6 months, maybe more if we’re talking about getting to grips with all the libraries, idioms and such.
But honestly, it’s no harder to switch to F# than it is to switch to Entity or WPF. They, too, are time-consuming. Not to downplay the effort required, but sometimes they say it takes years to make this transition. Let me repeat: it takes a few weeks to start writing code and a few months to get the hang of it. I say this both from my own experience and from the experience of others I’ve talked to.
Do you need to know C# before F#
– It’s clear that among those who use F#, most of them came to it from C#. Are there many who come to F# without C# experience?
– There aren’t very many people like that, and it’s quite hard for them, because all the libraries have documentation for C#, so one runs into examples from C# everywhere. But still there are such people, and besides, F# is taught at several universities.
There are those who try to learn F# after Python. The problem is that F# depends very much on .NET, and .NET is tied to C#. It’s the same situation with Visual Basic, all the examples there are also in C#. Hopefully this situation will change in the next few years and make the language easier to learn, this is one of the important problems right now.
– If students are given both C# and F#, they usually do it in that order, and then F# can be confusing to students. What do you think about the idea of reversing the order? If you introduce people to things like LINQ and subsets of monads first, would that probably make the language easier to understand?
– I’ve heard that people who first get acquainted with functional programming, then get totally confused when they start learning OOP, and start asking : how do you make immutability here? Where are the monads? This is a matter of habit. To a person who has learned functional programming, OOP seems strange and intimidating, and vice versa. That’s not to say you can’t start with functional programming, there’s a textbook that uses F# as an introductory language, Programming Theory Concepts or something like that.
– If it weren’t for the mentioned problems with C# in the documentation, you could safely recommend F# to everyone as a first language?
– Speaking of the F# audience – what audience is your "F# for fun and profit" site aimed at? Is the reader expected to know C#?
– At first it was almost exclusively about F#, and from there it largely followed my development as a programmer. Now it is not so much about F#, but about functional programming in general. For example, there are my articles devoted to Railway Oriented Programming, Property Based Testing, and many other things. And I’ve heard many times from readers that they have used these ideas in TypeScript or Ruby, so this is material not only for F# users. I hope these articles will be useful to everyone, including C# users.
Fun and profit
– The name "F# for fun and profit" ("F# for fun and profit") may seem strange to some, because functional programming is not usually associated with "fun". But do you think there’s a lot of fun in there, too?
– Yes. And I didn’t give this name to the site by accident. I wanted to stress that F# can be both useful and interesting, i.e. it is not just a language for academics. As I told before, by the time I decided to try F# I was very tired of my work and the language I was writing in. And with F#, I got interested again.
I don’t know what makes some languages interesting and others not so much. But I’ve never once heard anyone call Java an interesting language. Maybe it’s because in some languages you can get much better results in less time, you don’t have to spend time on typing and stuff like that. Anyway, I’ve had a lot of people tell me that programming has become much more fun since switching to F# after C#.
– On the subject of "benefit": you can hear that functional programming is not only interesting, but it pays well; developer salaries in functional languages are higher.
– Yes, that’s right. Companies that have determined that they need functional programming are willing to pay programmers more money. So I advise people to learn functional programming also for that reason.
There was a survey on StackOverflow a few years ago where it was found that F# has higher salaries than any other language. The situation may change, of course, but in general, programmers in functional languages are definitely paid more than programmers in C#. It is true that it is because functional programmers are much rarer now, in 10 years this difference may disappear. But now there is definitely an advantage.
Also, I’ve noticed that often employers are looking for programmers with F# experience, even if the job itself is not directly related to F#. That is, if a person has learned F#, they have most likely grown as a developer, or at least they are willing to try new things. After all, there are some programmers who don’t want to learn anything. All in all, learning F# clearly won’t hurt your career.
– So, F# benefits developers. But what about employers? Because if the owner of a company reads our interview, he will conclude that F# programmers are harder to find and need to be paid more. What are the advantages of F# from the company’s point of view?
– From a company perspective, F# reduces the amount of work done. Imutability, explicit dependencies, and other things significantly reduce bugs and simplify code maintenance. When some changes need to be made, it is much more likely that the new code will work the first time. It is a common saying about such code that if it compiles, it works. There are exceptions, but that’s usually true. With F#, it is not necessary to check null values; if types are written correctly, they do not get mixed up; many undesirable situations in code can be made impossible. Thanks to all these tricks, F# code can be written much faster.
The way I see it, when you write in F# there’s much more logic in your code, less boilerplate, and less unnecessary formalities that have nothing to do with the program itself. C# has lots of patterns – Visitor, Factory, Singleton, Bridge, while F# has none of that, just code that does what you need to do.
So you end up with much less code to solve a problem. I think it’s worth paying more money to the programmers. Of course, there are some companies that won’t spend an extra ruble, but others have an understanding that software gives a competitive advantage, and so they’re willing to pay for it. This is why Google and Amazon have high salaries – they specialize in software.
– People often complain that although the F# language itself is great, there are a lot of problems with the ecosystem – fewer jobs, harder to recruit a team, difficulty with documentation. What then are the reasons to prefer it?
– Yes, that’s true. That is, you have to compare, on the one hand, the benefits of having this infrastructure in C# and, on the other hand, the inevitable annoyance of everyday use of C#. For example, when you write in C#, you constantly have to deal with null values, redefining equality and the like, and every line of code is annoying in some way. With F#, this feeling does not exist. Yes, you have to pay extra effort for documentation and many other things, but the code writing itself is much smoother, so I’m willing to spend that effort.
To really compare any two things to each other, you have to ask people who have tried both. A C# programmer may have an opinion about F#, but he probably hasn’t written in it. So you have to ask people who have experience with both. And, in my experience, such people most often prefer F# because it’s easier to work with.
– You can see the uncertainty of developers about how much Microsoft will invest in F# support (while with C# everything is more reliable). What do you think about this?
– I agree, Microsoft’s focus is mostly on C#. I would say that there are two types of developers. One is programmers in large companies who are used to being Microsoft-centric, and so they use, say, Entity Framework and Visual Studio. And there are others who don’t have to wait for Microsoft; if Microsoft doesn’t do something, they’ll do it themselves. And this approach is common in the ops community, such as Python or Ruby developers. These people don’t wait for someone else’s permission; if something needs to be done, they do it themselves.
So, when it comes to support for F#, there’s really nothing to support there – F# is an optinsource language, the community of that language does a fine job of supporting it itself. Most of the improvements to the compiler are not made by Microsoft, but by the community. The same goes for tools like Ionide, a plugin for VS. All in all, F# has a very active community that doesn’t need much help from Microsoft. No one is giving up that help, of course, and it’s great when it’s provided, but there is no dependence on Microsoft. If Microsoft were to stop participating at all, I don’t think the community would fall apart.
– You’ve probably tried other functional languages up to and including Haskell. Why do you prefer F# among them – because you have .NET background, or because you liked the others less?
– I’ve tried many different languages, and many I still like, such as Smalltalk, which is generally an object-oriented language. But I’m doing F# more because I already had experience with .NET. If I used to write in Java, I’d rather switch to Scala or something like that. True, I know people who’ve written in both C# and Java, and they still like F# better than Scala because it’s simpler.
– Last question. You know F# very well, and yet in your reports you talk a lot about its advantages, so it is interesting to ask you : what, from your point of view, are its disadvantages ?
– It seems to me that many aspects of F# could be simplified without any harm to the language. This is unnecessary complexity, which I don’t think anyone needs. The language itself is quite good, but the documentation is worth working on. The tools for F# are not bad, but there are fewer of them than for C#. It’s better than other functional languages like Haskell, but still has room to grow.
In addition, I think the language could be made more accessible for beginners, making the process of downloading and running the language smoother.
The F# community is quite small, and there’s a lot of controversy in it, which may annoy some people. But I think the same thing happens in other programming languages.
Generally, when you first learn something, a lot of things are annoying, and you think – why are these things so stupidly arranged, how is it possible? And then you gradually get used to the system and this irritation goes away, because you learn that you have to behave this way, not that way. And this is true not only in F#, but also in C#, and in general this is true for any activity, not only in programming. As time goes by, you learn to avoid the drawbacks and concentrate on the strengths. I think this is what happens when you get used to F#.
But in general I agree with you, F# is far from perfect, and there are many aspects to work on.
Scott will speak at DotNext with by "The Power of Composition. We should not fear that this report is for F# experts: on the contrary, it is intended for those who have never had much experience with functional programming before, so the basic concepts will be explained there. Besides this talk, there will be a lot of interesting For dotnetters.