F# and Scala are now in more direct competition after Microsoft open sourced F# and .NET Core. They have many similarities but a distinctly different feel. It was hard for me to put my finger on the difference. This blog post investigates their design decisions and use cases. Starting with a brief overview of F# and Scala.
F# (F Sharp)
F# is a mature, open source, cross-platform, functional-first programming language. It was created by Don Syme in 2005 as a port of the OCaml language to .NET.
- Core: Strict, strong, inferred, hybrid
- Popularity: Some use in industry and backed by Microsoft
- Complexity: Easy to learn, but part of a big ecosystem
- Maturity: It is 14 years old and part of the .NET, so quite mature
- Tooling: Very good, both .NET based and F# specialized
- Cross platform: with Mono and .NET Core and JavaScript
- IDE: Visual Studio, VS Code
Scala
Scala combines object-oriented and functional programming in one concise, high-level language. It was created by Martin Odersky in 2004.
- Core: Strict and lazy, nominal and structural, hybrid, implicit for IoC
- Popularity: Very popular. No 13 on Red Monk June 2019 list. Spark is written in Scala
- Complexity: It is a quite complex language, but it is easy to get started with
- Maturity: Very stable. Run on JVM, well integrated with JVM ecosystem
- Tooling: Great build tool and package managers
- Cross platform: JVM and JS. Also early work on native / LLVM version
- IDE: IntelliJ, VS Code, Eclipse
Microsoft Open Source Bet
Choosing between F# and Scala used to be pretty easy. If you were doing Windows development you would use F# if you were on an open source stack you would choose Scala.
In 2012 Microsoft open sourced F# and started porting it to Mono a Microsoft supported cross platform version of the CLR. That was cool but not something I would run production code on.
However, in September 2019 Microsoft released .NET Core 3 an open source cross platform version of a big part of their SDK and also a first release of Apache Spark for .NET.
After this .NET and F# are serious contenders for being parts of an open source stack.
Relation to Java and C#
You might think that F# is just the .NET version of Scala and moving from Java to Scala is similar to moving from C# to F#. This is not the case.
Java was a small and simple language with a lot of innovations but some annoying problems. A big part of Scala appeal was that it was a better Java with more features.
C# was also made to be a better Java. It fixed some of the flaws in the original Java, e.g. auto boxing of integers, generics and lambdas. C# is a great but also very big language. F# is more like a leaner version of C#, with less features.
Collection Libraries
Scala has made a big effort to make a full set of immutable and mutable Scala collections and make different Java collections look like they are native Scala collections.
I tried Scala in 2007 it had generic and could use Java generic, but either you were programming in Java or in Scala. This took a long time to get this right and cost was that the standard library code was very complicated. This is not really a problem for the user who won't see this.
Generally, F# is using a few collections: Arrays, lists, seq, set and map.
It is a bit messy to bridge the OCaml and the C# heritage, especially map / dictionaries are clumsy.
Monads
A monad is an important part of functional programming. It is a general principle to express a sequence of operations and work on a lot of different data types:
List, Seq, Future, Option.
Scala monadic for comprehension
Scala's version is syntactic sugar over flatMap(). It is more flexible, it can mix two types of monads say List and Option. Scala's monad will also return the same type as the input type.
F# monadic for comprehension
F#'s version of the monad computation is called computational expression. It has more features than Scala's.
Classes
Classes are considered an anti-pattern by functional programming purist. Some problems with classes are:
- A class maintains state
- A class creates a custom language instead of reuse of operations
- Inheritance is crating tight coupling
Scala has a very sophisticated type and class system and classes are central part of Scala.
F# has support for classes, but it is billing itself as object programming not object-oriented programming. It is made to use classes defined in C#, but will often define objects with methods without a full class definition.
I like that F# is exploring more lightweight alternatives but classes are easy to create and feels natural to use.
I like that F# is exploring more lightweight alternatives but classes are easy to create and feels natural to use.
Type Classes, IoC, DI, Type Providers
Type class is a powerful abstraction that can make a third party class implement an interface. It plays an important role in Scala and are implemented with helper classes created by implicit.
Scala has developed these ideas to the point where you can do logic style programming with implicit. A lot of the more sophisticated category theory like programming is based on this.
You can do inversion of control and dependency injection in F# using libraries.
F# has type providers that on the fly generated typed access to a lot of different data sources, e.g. a table on a webpage.
F# has type providers that on the fly generated typed access to a lot of different data sources, e.g. a table on a webpage.
Design Decisions
F# is white space indentation-based language. Scala is a curly bracket language.
F# is a lightweight language with strong compose-ability.
Scala has sophisticated type system, including type classes, this unifies a lot of different classes and facilitating reuse.
F# program feel a little more like a loose collection of definitions while Scala program feels more like a carefully packaged system.
Conclusion
F# and Scala have a lot in common. To a large extent you would still chose F# or Scala based on your platform choice.
Both languages are very well suited for building back end programs that can interact with a universe of libraries written in C# or Java.
F# is more lightweight than Scala. This makes it great for data exploration and great for building small scripts. It still remains to be seen how well supported Spark is going to be for .NET.
From a language evolution perspective, the object functional hybrid has been very successful. F# and Scala's different emphasis has produced different language from similar goals. I am very happy that we now can compare their design decisions on merit not just compare .NET and Java ecosystems.
This article is an elaboration on my last blog post Typed Functional Languages 2019.
Disclaimer I have been a happy Scala user for years, and only occasionally use F#.
No comments:
Post a Comment