Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Having used and enjoyed F#, I ended up programming in Scala which is almost the same language, despite the huge superficial differences:

- 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.



Ultimately these higher-level requirements like JVM vs. .NET are the biggest factor in deciding a language. For example, my latest project need to run on Azure Functions (consumption plan, has cold-start) for cost reasons, so the deciding factor was "which language has the lowest cold start time?" If you're doing ML model design, you use Python because that's what the notebooks and libraries are written in. At any given moment, OS/cloud platform support, library availability, and desired app model has way more impact on choosing a language than design.


I can echo this. I'm working in F# in my day to day. While I like the language. I find the tooling IDE and other essentials are missing. I spent several weeks fighting swagger generation client and server tools. Something that just worked on the jvm.

I bounce between Scala and Kotlin. But as a Linux dev I find the JVM far more forgiving.


Re F# tooling and IDEs: sadly the churn around the transition to .Net Core has really hurt F#s tools. Things that were stable and working since inception, and enabled highly productive workflows, have been trampled by missing features and shifting boundaries on the new platform.

That said: it seems it's finally coming around, as .Net Core matures and gets more mature secondary tooling, a lot of the little blocking issues can finally be addressed.


I am new to programming...wanted to import and process tables from https://en.m.wikipedia.org/wiki/Megacity Was using ionide on vscode But not working because .NET CORE is not supported

Returns the suggestion to switch Fsac.Runtime to netcore after I get the error fs0039 HtmlProvider is not defined even though Intellisense recognises it..

...refer below

https://github.com/ionide/ionide-vscode-fsharp/issues/973


I strongly recommend giving Rider a try for F# development - I've been really impressed.


Is F#'s type system sophisticated enough to express type classes, higher-kinded types, and/or existential types? Scala's implicits and related language features can go a long way down those roads, but I know very little about F# other than "it's like Scala but on the CLR" and am curious what the story is over there.


F# doesn't support any of those features you listed. If you want ad-hoc polymorphism there are a few hacks available: https://withouttheloop.com/articles/2014-10-21-fsharp-adhoc-...


F# does not have HKT, and it shows in the compile times.


I haven't really played much with Scala but I would say there are reasons why I will not and stick to F#:

- JVM is less efficient for generics than the CIL (casts happening at runtime underneath).

- I've read about horror stories about tailcalls in the JVM world.

- There's no way to build an iOS app with Scala (i.e.: https://stackoverflow.com/questions/13460780/any-way-to-use-... ), while you can do easily with F# thanks to Xamarin.


The answers there aren't up to date, here's a new answer https://stackoverflow.com/a/53756826/756809


There is way for free with CodenameOne.

And there is another way paying for GluonVM.

EDIT: corrected my statements based on comment below.


Codename One has a free tier that allows you to do pretty much everything and allows you to use it commercially https://help.codenameone.com/en-us/article/is-codename-one-f...

You can grow the build quotas as well to support larger applications. Furthermore, you can use the open source pieces of Codename One for free without the build servers. There is no restriction on that.


Thanks for clarifying that up, I do not follow up on it that closely.


JVM knows nothing about generics. What kind of casts are you talking about?

Trampolines are a common technique to implement tailcalls on platforms that don't support them natively. What are the horror stories then?

Why would you bother with F# or Scala when iOS has Swift?


> JVM knows nothing about generics. What kind of casts are you talking about?

Precisely! because the bytecode doesn't know about generics (it's syntactic sugar in higher levels, i.e. Java), then casts need to be performed at runtime (e.g. when getting an item from a collection).

> What are the horror stories then?

https://stackoverflow.com/a/18196685/544947

> Why would you bother with F# or Scala when iOS has Swift?

Haha, thanks for agreeing with me that Scala is not good in this regard. When I choose F# over Scala is because it can run in any platform. I'm not constrained.


I suppose you meant boxing/unboxing. If so, yes, that's necessary for primitive types. As for regular objects, no casts are needed.

Regarding TCO, that's a well known limitation of the current Scala compiler. Hardly a "horror story".

Let me assure you, there are plenty of platforms where F# is nowhere to be seen. Thus, "can run on any platform [I care about]", which is a different set for different people anyway. For example, F# does not run on JVM, does it?


Dude, JVM is not a platform but a runtime. Why is it relevant to run F# on JVM? The important thing is to run F# in any hardware/OS, that's my point.

> As for regular objects, no casts are needed.

Are you sure? See https://stackoverflow.com/a/10126425/544947

> Hardly a "horror story".

F# doesn't have this limitation and F# does tailcalls by default instead of having to explicitly remember to decorate it with the @tailrec attribute.


You have a pretty narrow definition of a platform. Consider https://en.m.wikipedia.org/wiki/Computing_platform

Yes, you are right, I didn't consider the checkcast instruction.

Yes, F# does not have this particular limitation, but has few of its own in different places. Most notably, it lacks HKT (arguably, because of CLR awareness of generics).

BTW, alternative approaches to stack-safe recursion do exist in Scala. For example, https://github.com/slamdata/matryoshka


> Yes, F# does not have this particular limitation

And guess what? it doesn't have it because F# doesn't run on the JVM! If it run in the JVM, it would have it. So your obsession with "runtime" as a platform not only not useful, it's asking for trouble! ;)


Sounds like you are confused about what @tailrec does.

@tailrec is not necessary to enable tailcalls.

All the annotation does is error if a function is not able to be optimized for tail calls.

The (attempt at) optimization takes place either way, you don't need the annotation unless there's some doubt in your mind.


Note that there is also ongoing work to bring the native compilation to Scala[1].

[1] http://www.scala-native.org/


There are similar efforts on .NET Core side [1].

[1] https://github.com/dotnet/corert/blob/master/Documentation/i...


https://youtu.be/6P06YHc8faw?t=225

Just watched this video about Scala 3 last night and the list of features Scala pioneered in a mainstream language is fairly incredible.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: