- Indentation delimited blocks vs curlies
- CLR vs JVM
- Whitespace vs Parenthesis for function calls
- Currying by default vs currying optional
Despite all this, when you actually start coding, it's remarkably the same:
- Immutability by default, transformations rather than mutation
- Less classes with embedded implementation logic, more "dumb" records with external functions
- Structural pattern matching
- Tagged unions
- Type inference
- Convenient definition of record/struct-like data types with free copy-constructor
- Operator overloading
- Easy FFI to external libraries in a different paradigm
- Easy "dropping down" to mutable, imperative code (e.g. for performance, or interop)
- Both have lots of syntactic and semantic warts and corner cases, though few enough you can live with them
- Garbage collected, multithreaded, JITed runtime
- Both compile to Javascript
While every single feature looks totally different on the surface, starting with a totally different syntax, the two languages are more the same than different. If you look at the tutorials linked from that page, all of them can be translated almost line-for-line from F# to Scala (and vice versa: take any random Scala tutorial, and you can trivially translate it line-for-line into F#)
Scala brings with it a bigger ecosystem, both in Scala and from the JVM, and better tooling support in general (Both Scala-specific, as well as general JVM tooling which all works with Scala: profilers, debuggers, package managers, ...), and slightly more seamless platform interop (Scala <-> JVM is less jarring than F# <-> C#), which is why I ended up sticking around.