Any language developed on dotnet platform will always be in C#'s shadow. F# is much nicer to write than C#(for now), if you need to develop on dotnet.
Any language developed on dotnet platform will always be in C#'s shadow. F# is much nicer to write than C#(for now), if you need to develop on dotnet.
What are my options?
- PureScript on web and Node.js
Can use NPM packages! Node.js as a run-time lacks features like shared memory across threads. PureScript is still too early IMO.
- Scala on JVM and web using Scala.js
Not a bad option, although the language is very complex. More towards the OOP end than the ML end in the spectrum of language design. JVM can be a good or a bad thing, depending on what you are doing.
- F# on .NET Core and web using Fable
Simple functional language with access to the .NET ecosystem. ASP.NET has great performance. Access to NPM packages on web. Lacks some advanced type-system features in Haskell, OCaml and Scala. However, the community has a pragmatic focus as a result.
- OCaml and ReasonML
ReasonML has limited backing from Facebook. OCaml has support from a few financial institutions (e.g. Jane Street) but it's not on the same level as what a big tech company could provide. Tiny (but high quality) community and ecosystem. OCaml has great single-threaded performance but mult-threading is not quite ready. Already small community split by compiler extensions and standard libraries.
- Haskell and GHCJS
Again, tiny community and ecosystem. Beautiful language, but lazy evaluation has bit me too many times. Steep learning curve since newcomers cannot fall-back to OOP and imperative code.
- Elm
Tiny ecosystem, tied to Node.js (see PureScript). Interop story with NPM modules is worse than PureScript.
For me, F# is the clear winner.
If you aren't particularly interested in functional programming - maybe you just use some delegates here and there - then C# is a fine choice. Otherwise, C# quickly becomes awkward compared to F#. Besides, C# to JS options are not as mature as Fable.
I wonder what is easier for a strong OOP developer to learn, Lisp or ML?
ML, depending on the flavour gets pretty how one combines functors, aka generic modules, which is similar to component based programming like COM, or just plain objects as in OCaml.
Now the immutability isn't as hard to adapt to as one may think.
Also I bet that The Art of Metaobject Protocol reference implementation can be ported into Clojure without major issues.
https://clojuredocs.org/clojure.core/defprotocol
"A protocol is a named set of named methods and their signatures"
Such protocols are not a language feature of CLOS.
AMOP describes a 'Metaobject Protocol' (MOP) and has a tiny example implementation (called Closette). This is entirely different from what the 'protocols' feature does in Clojure. A 'protocol' in AMOP is informal.
What AMOP actually describes with its MOP, is a meta-level of meta-classes and generic functions, which implement large parts of CLOS itself. Such the classes, generic functions, methods, slot descriptors, etc. are CLOS objects themselves.
Clojure supports a form of multiple dispatch, but the dispatch mechanism is also very different from CLOS - for example it uses a dispatch method per generic function, selects one method and has no idea of a next method. CLOS for example uses a built-in dispatch mechanism, multiple class-based dispatch hierarchies for multiple arguments, using a set of methods which are selected based on the class hierarchy.
https://clojure.org/about/runtime_polymorphism
Typically it is not a good idea if Clojure uses a name for a feature, to generally think that this is similar to a feature with a similar name in Common Lisp -> 'protocols' and 'meta-object protocol' are two very different things.
Porting the CLOS MOP to Clojure would be possible, when one first implements CLOS in Clojure. Otherwise it makes very little sense, since Clojure does not by default support the (older) view of object-oriented programming of CLOS. Something which the Clojure designer thought of a feature: getting rid of things like mutable objects, class based inheritance, class-based OO, etc.