F# is the best coding language today
danielbmarkham.com
danielbmarkham.com
IMO C# is picking up a lot of small things that make it incrementally better than it was before, and at some point it's not worth the hassle to go to F#. F# features are gradually added to C# so C# developers have time to pick them up as well.
I've heard of F# only projects doing great, but I think you need to have a team committed to doing F#. Back when I was into Clojure they had this mantra of "add Clojure to your work projects as a library and pretend it's just this small thing you used to solve some problem because it's all on JVM and Java compatible and then keep expanding on it" - I think this turns out terrible in practice.
No regrets, canopy was an absolute pleasure to use https://lefthandedgoat.github.io/canopy
The victim of this pattern is not you
I'm not saying you can't introduce new ideas into your organization, but this is where the politics of development comes into play. You need to get buy-in from your team and management, otherwise you're intentionally hurting your organization.
You become critical in the short term, but also critical to the business to replace in the long term, in the same way that a vendor tripling their price often results in short term profits while customers transition off of them, leading to a long term decline in revenue.
You become a single point of failure for the org, so you're more important, but you're removing value from the org because you're making it more difficult to scale the organization.
Some places have toxic cultures so that's the norm, but if you're fortunate to be at a better place, don't force their hand to go down that route!
(There's also the aspect where if you're the only person who can do X, but now someone needs to do Y which will actually be ten times more valuable to the company than X, you've closed off that opportunity for yourself!)
If you have a team looking for a functional language on .NET it's amazing - so I don't dismiss it - it's just a very niche thing on .NET platform.
What objective measure can someone use to determine whether F# is the best choice?
What is possible however is to first analyze the core attributes of the techs which are relevant for the project and team such as: good supported libraries for the problem, support for immutable data-structure, expressiveness of the type system, experience of the team with the tech etc. You can then decide which tech fits better the environment. If still undecided you can try to build a prototype on a short period (at the risk on giving up on technologies which are hard to learn but could be rewarding on the long term).
I used to be a very big fan of a certain functional language, and invested serious time and effort into projects in that language, but hindsight tells me every single time it was a mistake. It was a mistake because if you cannot hire people to do the work then the project dies when it needs to grow.
People used to do very big projects in COBOL, which most hacker news readers have never even seen, and as someone who did some COBOL, I can confirm that it was absolutely terrible, but the projects got done and by and large with less tech stack Jenga or superfluous trash that infests so many projects today. COBOL died when the majority of people moved on, not because st80, pascal, ada and C were better, but because the industry switched to platforms where the dominant languages were day one different: pascal and C. Mac, Windows, the Unix workstations.
Maybe those platforms used other languages because they were better. Certainly I can’t imagine the Mac built with COBOL, FORTRAN, bcpl (worked for amiga, somewhat), etc. but the dynamic of leaders is different from the dynamic of followers.
Your second point is about platforms. A FP language hosted on a popular platform has a lot to gain. That's the Clojure story. Rich Hickey tried different solutions / languages before but only Clojure was successful enough. Because it's tied to the JVM.
But... nowadays most popular FP languages are hosted on a popular platform (JS/Web, JVM, .Net) so if a FP language builts a community that is big enough (no need to be big like Python) it will be sustainable.
Last comment: if you think about sustainability on the very long term, such as COBOL projects, then choosing the default language of the platform (JavaScript for the web, Java for the JVM etc) may be wise (because the platform is more likely to die after the other languages). The truth is that most software project don't have such a long life so it should be only one criteria among other for the choice.
So to conclude given a good choice for a platform (BEAM for distributed systems for example) I think languages do matter, because they offer different trade-offs (less state bugs with FP languages for example).
The whole mental framework of hiring for a language comes, I think, from HR/business people assuming that programming languages are like natural languages and that language experience is a central, fixed component of a candidate's identity.
In large parts of the industry we simply don't believe this at all, interviews are about algorithms / problem solving and experience filters at senior levels are about business problem domains. Getting up to speed in whatever language is just part of onboarding.
I love F#, but don't think it's ideal if it's shoe horned into a C# project. You then have this boundary layer you have to maintain.
agree. C# is kind of morphing into F# with new features like record.
An OO language with record types and pattern matching expressions, plus a vague hint of union types in the future; is not a functional language. Depending on who you ask, it's either a quasi-functional OO language or a bloated OO language. I used to be in the first camp, now I lean towards the latter.
Over time, projects morph into the average of their framework. If you started off badly, if it survives long enough eventually someone will refactor it into something acceptable. If you start off using FP features, eventually they will be eroded away; through friction with external dependencies, or later developers being less invested in the paradigm. In both cases you're usually left with an inconsistent codebase.
When people say that C# is morphing into F#, my usual thought is 'have you ever seen an FP project?' Take some time and read some FP codebases, and compare them with a typical C# codebase.
(side-note: one of the most widely used FP language for web development is elixir. There are a few good open-source elixir projects you can read to get a feel for the structure. Almost all elixir projects follow the same structure, and it's about as anti OO/SOLID as possible, yet still conforming to a vague onion architecture.)
Programming language adoption is based on politics, not technical merit.
This isn't inherently bad, but is important to remember.
Languages are successful due to the community that rises up around them, far moreso than anything inherent to the design or quality of the language itself.
Which can be correlated, but not necessarily so.
This is overly reductive, but here's an example: if you have 3 developers, and 1 will be twice as productive in F# and the others will be 10% less productive, it's probably practical sense to switch, but the 2 developers will resist it, and it may fail for political reasons.
And yet it happens all the time. And the decision is rarely based on anything but a veneer of technical merit.
That's how politics generally works: there always has to be a plausible "objective" reason for something, it just doesn't have to be applied uniformly or even actually true.
I've seen countless migrations to React from other equally capable frameworks because "everybody uses React" it must be the best tool!
I've seen companies picking up Python because if you wanna do ML you gotta use Python, right?
Anybody can write Python, right?
Except now you have a Python codebase written by people that pretend to know Python, while they really don't know how to write a maintainable software program in any language, it just happens that Python is the only language they "know".
And now everything sucks, but at least it's trendy, right?
Programming languages are tools, if you hire someone competent in Ocaml but force them to use Java because "it's more maintainable" you now have two problems.
IMO
At my company there have been several devs trying to introduce Clojure as well as parallel forays to introduce Kotlin. Overall, Kotlin has caught on and spread much more rapidly and with less effort.
This is not a statement of which languages are "better" given all things equal or what problems each are suitable for, but in my first hand experience it is easier for the average Java developer to pick up Kotlin. Of course we as a company are also cognizant of the IntelliJ lock-in as I suspect using any other editor would run into the same random bugs / autocomplete annoyances that the GP experienced.
There's your politics. Kotlin is succeeding because of it's ties to a very popular Java IDE, so developers already using IntelliJ tend to trust it.
It wouldn't do nearly as well without that built in base of support.
It's always politics.
Me, I like sight seeing. A bicycle ride sounds brilliant. Even though it is much slower.
“Brilliance” is a human attitude towards technology. It is not an intrinsic property of technology.
A country which would have made different political decisions may have decided to not provide a direct airplane flight, or as good of an interstate road system that makes the drive possible. They may have provided high speed rail instead that could have potentially been better if that’s what the country had chosen.
Honestly I feel kotlin doesn't add much to modern java, and if possible I think it's generally better to use the native language to the platform. Probably a reason why kotlin is not that popular on the backend where people can use modern java :)
I think jimbokun statement is 100 percent correct which doesn't mean kotlin is a bad language.
In that case, I hope you won't mind that I'll be ignoring the rest of your opinions on this particular topic.
Scala’s an interesting case, it rather did catch on.
My experience is a micro-scale observation that it did not take much campaigning to convince developers to try it (given the existing level of support backed by Jetbrains).
The similarity to Java, something many developers already know, is an appeal to current popular sentiment. You can advocate the superiority of Clojure's S-expression inspired syntax or immutably data structures or pure functions all you want, most people will just pick something close to what they already know.
The reason might be, that Clojure is following a completely different paradigm and people are not willing enough to learn it.
> This is not a statement of which languages are "better" given all things equal or what problems each are suitable for, but in my first hand experience it is easier for the average Java developer to pick up Kotlin.
Yep, I would expect that to be the case.
There is a lot to learn for the average Java only (so far) programmer to really get Clojure.
This is a very serious problem in a production system and it's not a political problem. Having a mixed language system is never as maintainable as a mono-language system, assuming that mono-language is up to the task.
>they leave and now the project has this magic F# part that nobody really knows how it works but everyone knows how to work around.
You cannot add the best features of F# to C# without making it a fundamentally different language. You're not gonna make C# into a type-inferred FP language by bolting on some random half-understood bits anymore than you can make a cat jump better by gluing rabbit legs onto it.
It's the core paradigm and philosophy that makes it great, and if anything, what I've seen hold it back from its potential is insufficient support requiring essentially importing C# idioms into the language just to interop with existing libraries.
Which is really a positive - if you start a new effort in F#, it basically self-selects for the most technically curious or proficient devs. Most corporate C# code-slingers are fearful of learning it or putting themselves through the mindset shift required to grok basic FP principles. "Do you know or are you interested in learning F#" becomes the only interview question required. But I do agree, if you have to build a team around the "least common denominator" then pick the boring tech stack and go.
But I share some of your reasoning and am curious how this actually plays out (I haven't seen any examples so far). One project I worked on, when starting they wanted to do Clojure and they ended up using RoR because everyone was using it and Clojure was a hiring concern. In retrospect RoR fell out of favour, there's a bunch of vacancies for it but it's not very hot so it's hard to find devs and they are forced to take "learn on the job" just like with Clojure, plus you need to compete with a bunch of employers looking to support their projects in now out of fashion stack. I think using Clojure would give them a unique candidate pool and be a hiring differentiator. But that's just speculation. I haven't actually seen how this choice works out in practice.
it just selects for people who have hipster level enthusiasm about function programming. That doesn't mean proficient.
Many talented developers have a life of their own, and can do well without changing the language.
That's why Joel said 'smart AND gets things done'.
This is very accurate, and speaks more towards the sociotechnical systems at play here than anything else. It's not just about being a fan of F# and getting management to approve you using it. You need to cultivate an environment where others want to use it too.
The problems with F# are that .NET was originally Window's only causing the creation of a separate run-time in Mono, there were breakages when .NET moved from .NET Framework and Mono to .NET Core (now .NET 5), problems with messaging F# as a C# replacement, biased perspectives of F# as a Microsoft product, Microsoft's lack of investment in and marketing of F#, and F#'s overall ecosystem. There's also the push and pull that comes from some developers wanting to make F# into Haskell, whereas I think that's against the natural settled state of F# as a multi-paradigm practical language.
One can write F# basically as one would write Python, yet F# comes with a host of improvements over Python. One could even go full OOP in F# like one would in C#, again with improvements of conciseness and readability. With F#'s functional paradigm but non-insistence on purity, one gets a language that allows you to write beautifully correct code that works and doesn't fight against you. I use F# in my side projects and also some small work projects, and when using F#, it feels like I'm just translating a specification into code where when done, the code just works.
Unfortunately, the F# ecosystem is not as coherent as others. Probably the comparison I would make is to Elixir. Although I'd argue Elixir isn't as nice of a core language as F#, Elixir's ecosystem and coherence across that ecosystem is very nice and yields a great development experience. The Elixir community has rallied around certain ways of doing things and frameworks where it feels F# is a little more spread out.
I agree with this; it should of never be marketed this way. For me C#, once you get past a lot of the initial ceremony of the language and all the libraries/OO patterns you need to learn (DI, mocking frameworks, etc) the gap between C# and F# gets a lot smaller. C# isn't a bad language and has a lot of features, it just also has a lot of history that adds complexity. IMO the benefit of F# and other newer languages is about simplifying things while keeping the same level or more expressive power. If you've already learnt all the patterns and frameworks in C#, have reasoned around the historical complexity and the ways around things seem second nature to you there isn't much to gain and some things to lose (e.g. familiarity, politics, fear of change, support).
Grab a Go, Python, JS dev however and show them idiomatic F# code vs idiomatic C# code (with tests, and scaffolding) and from first hand experience I've seen what they choose. Even more so because typically these people typically use tools like VS Code and not a full blown IDE, where F# has the advantage at present.
F# - ML + .Net
Clojure - Java + jvm + lisp
Rust/OCaml - System Programming
Both F# and Clojure give you access to probably the two biggest ecosystems, but they are obviously put them at opposite ends of the programming paradigms spectrum, but this makes learning both less redundant
Rust and OCaml, are probably what you should use if you want a compiled system language
Honorable mention PureScript, because haskell + Javascript (but F# will take you close and is more practical)
F# seems nice and if I had to pick C# or F#, I would pick F# but I see Clojure as conceptually stronger, easier to explain and teach, to finish projects quickly and run them reliably. Immutable datastructures, the REPL and somewhat related hot-code reloading on the backend and frontend also really is something. (I know, F# has a "REPL" but is it more a Shell or a REPL e.g. running even in production?) Perhaps I should update my views about F# sometime. With my current knowledge I see it as somewhat inferior to the Clojure/ ClojureScript duo and the related ecosystem.
I can see static typing helping e.g. with compilers, low level software where every clock cycle and byte matter and some specialized stuff. I don't see much point in static typing in a language like Clojure.
Most static typing folks have backgrounds in dynamically typed languages, and it's this experience (not dogma) that informs their preferences. The inverse (people have extensive experience with statically typed languages but developed a strong preference for dynamically typed languages) seems far rarer, at least nowadays where the canonical statically typed language is not C++.
Personally, I think one of the killer features of statically typed languages is that they make it difficult for people to write code for which the types would be very convoluted. In other words, statically typed languages provide rails which guide poor developers toward better habits (and incidentally, these same rails make it very painful to port a lot of JavaScript to TypeScript or for many JavaScript/Python developers to use statically typed languages).
From my understanding, the lisp language communities tend to select for programmers who have good habits already so they probably don't benefit from this property as much as other dynamic languages. Similarly, lisp programmers can use metaprogramming without it turning into a complete shit show, which is what almost invariably happens whenever Python programmers start dabbling in the metaprogramming facilities of their language.
That said, there are other advantages to static typing besides preventing classes of errors. For example, a lot of important documentation is generated and guaranteed by the type system. A perennial problem in dynamic languages including lisps is documenting the types. If you say something is a "file-like" object, what does that mean? Does the callee require that the object has a read() method, or does it also need seek(), close(), etc? And very often you don't even get "file-like object" but rather just a terse variable name (lisps are especially guilty of this, in my experience) or the documented type is outright incorrect (typically someone changed the code but didn't update the documentation). Additionally, you get a lot more powerful tooling, because the types can be reasoned about statically (which isn't to say Closure lacks powerful tooling, but rather that its tooling is powerful in spite of dynamic typing).
Right, this is exactly my point. People think these languages (especially as they were a decade or two ago) are representative of statically typed languages.
> Static types are at the top of the list of things that contribute almost nil and cause a huge amount of development overhead everywhere.
This is your dogma, not an established fact.
I'm glad you like Closure; no doubt it's a fun, useful language. It's probably even better than Java or C++ for many things. I'm only saying if you try different languages you might see that there are tradeoffs in features. You might still think Closure is the best, but you might at least understand why people appreciate static types.
Certainly, but there are lots of factors beyond static types vs dynamic types. For real world projects, I might similarly use Python or JavaScript over Haskell because it will be easier to find developers, libraries, and tooling. That doesn't impugn static types, however (on the other hand, depending on the project, Haskell might be the better tool).
Indeed, the type system is a relatively small, overemphasized facet of any programming language. See my comment here for elaboration: https://news.ycombinator.com/item?id=27784762
I'm not saying this as a die-hard static typing fan. I wrote Python for years, have written JS professionally most of my career, and spent 2 years writing Clojure professionally. I'm comfortable with dynamic languages. The Clojure codebase was the most stable I've been on (including typed languages) largely due to the senior team and excellent QA. The only problem I had with it was when business shifted from a subscription model to an a-la-carte model, which required manually reworking a LOT of maps to match the new requirements. This is considerably more painful in a dynamic language than it is in a static one.
There IS a downside to static typing in terms of verbosity. I've seen Java codebases where half the code was there basically because of the static typing. More advanced type systems do not suffer from that problem. I'm fine with OCaml / F# / Rust / Typescript.
Manual rework of maps seems like something that a good IDE or a small script should be able to automate, that is the point of Clojure being a data structure (EDN) after all - you can do stuff to the code as if it was data. Maybe there were specifics not allowing such sweeping changes, would love to hear more if you can share more about it.
I have a colleague which became 18 just a few days ago. He newer heard of Clojure(Script) or CSS before late last year and started actively learning it sometime after that. Jan is able to work on considerable amounts of code for our new landing page that will have some special interactive OrgPad embeds in it. He didn't have much difficulty navigating Clojure or our code base considering he did most of the work after school and on weekends basically as a learning exercise. Of course, he is getting solid guidance by the team. Our CTO Pavel has 20+ years of experience as a programmer/ software engineer and can do code reviews with Jan, so that helps. It also doesn't hurt that Jan is very smart, basically hand selected over multiple years by our CEO Vít who led a mathematics course for children/ teens and as such known Jan very well. Giving Jan a chance like this is basically a pilot combining normal education with practical, professional experience. Something like a very long internship on steroids :-)
I would still stress that static types are much less valuable than good variable/ function names and documentation/ clear code in my opinion and that maybe the complexity static types introduce isn't worth it overall. I also don't think, that static types as seen in e.g. Java or C# add any discernible degree of confidence - else somebody on the team would notice already. Jan didn't have problems navigating the code base even though most of the technologies, the language and the code base were completely new for him. Yes, anecdotal but I think it really is a valid and very important point.
My point of reference between typed and untyped code is primarily with Typescript and Javascript since that's 99% of what separates the two. For what it's worth, I do have 21 years of experience and have been lead on my projects for a number of years. As the lead, I get enough benefit from the type annotations that I've told co-workers to just any type anything they can't get working immediately and I'll fix it in code review. It's enough of an overall team velocity increase and easier code reviews that it's a win.
I'm not trying to argue with your experience. Dynamic languages work fine for building products and Clojure is my favorite dynamic language by a significant margin. I'm sure I'll write more Clojure in the future. I'm just trying to explain the benefits since I had the same mindset 15 years ago and now prefer static types. I'll mention that don't particularly like C# or Java and their type systems are not expressive enough for me to prefer over dynamic language.
> I've told co-workers to just any type anything they can't get working immediately and I'll fix it in code review
If you’re co-workers aren’t able to work with the types, how can they receive any benefits?
Not everyone is at a hyper growth place, but those that are would have zero luck with this pattern.
There's plenty of distance between unable to work with types at all and knowing the full breadth of the TS type system. I've worked with plenty of people who weren't enthusiastic about types and this is my way of handling those objections. Even someone who doesn't know/care about types gets the IDE features from the types.
I have yet to have someone persist in sending me lots of any types past two weeks because having your work constantly corrected is embarrassing. I don't expect everybody to care about the type system past generics so if someone wants to write a basic index type instead of the more correct keyof or opts for any over figuring out a conditional intersection type, I'll take care of it in code review. I'd rather have them writing code than reading TS documentation to wrangle advanced types and people do look at the commits when they go in and learn the tricks over time.
They come in different forms. Some can rely heavily on inference (Typescript) and some need to be very verbose (Java)
There are structural typesystems (Typescript) and nominal typesystems (Java)
In a structural typesystem the contents of a type can be compared to another type and match, whereas in a nominal typesystem it has to be the same type id to match. The former is more dynamic than the latter.
I don't like Javas typesystem but I like Typescripts typesystem because it's more flexible and doesn't force you to be verbose (you can for example only type function arguments and let it infer the rest)
One benefit I haven't seen mentioned here is the ability to refactor code with confidence and less need for unit tests.
For example comparing Javascript to Typescript; If I change a functions argument that is used in many places, the typesystem will give me a list of other code where the function is used I need to change in order for everything to work again.
In my experience, having written Clojure professionally in three different organizations over a period of close to a decade, static typing would have helped tremendously in producing maintainable software that allowed new developers to come into a project and get up to speed quickly, and build out more features without struggling to overcome the burden of endless boilerplate and incoherent abstractions, which Clojure makes easy. Which is to say, every Clojure codebase I inherited was a mess, and the tools Clojure provides to mitigate the problems of sharing a big codebase among a team of programmers are insufficient and place a tremendous burden of manual labor on industrial programmers--especially spec, which ironically produces exactly the kind of boilerplate pain and maintenance labor that Clojure apologists blanket-accuse statically-typed languages of producing. This directly and meaningfully impacts productivity and efficiency, and of course helps amplify bug creation as well.
> If I pass garbage to a clearly named function, I get garbage out as with the static type system.
Yep, and for the most part the only way to figure out what functions receive or return in Clojure is to either read the code, or actually call them. Relying on other programmers to be consistent and coherent in their naming is not really a great long-term approach...go figure. And, note that a side effect of this is that you often don't find out until some code is in production that you are passing garbage data around. AND that's leaving aside how badly most libraries are documented--even core libraries, how type information is rarely if ever shared in library documentation, and how Clojure doesn't enforce any kind of purity on functions so that basically, any function called anywhere can be doing basically anything.
Really it's not even about not having static typing--which is not a silver bullet, and absolutely has tradeoffs--but the fact that the community seems fundamentally immature and unable to discuss software engineering topics (static typing especially) without turning it into an emotionally laden battle between tribes, vs. a comparison between different tradeoffs. Simple vs. easy indeed.
I really did enjoy the language at one point, and credit it and RH for introducing me to the world of functional programming, but at this point I doubt I'll ever write Clojure professionally again. However if I do, it will be with a team that understands its strengths and weaknesses without attachment to emotionally-driven arguments about static typing, or whatever.
With great power comes great responsibility. The things you describe all seem like a problem of inheriting a code base written by people without much organizational discipline ("was a mess") or working with people ("Relying on other programmers to be consistent and coherent in their naming"), that don't have a coding discipline. Such things should be caught in a code review or perhaps cleared at the design stage. How do you want to work with people, that are not able to communicate their intents clearly to a human? How do these people "talk" to the computer through their code, are they partially guessing the "correct" code? Are these programmers perhaps producing a mess independent of the codebase or language?
I am really sorry for you, it must have been hell. I know Clojure(Script) isn't the silver bullet many people make it out to be. The programmer still has to be quite competent and quite disciplined at times but Clojure can and will support you - that is my experience. I have seen my fair share of stuff, professional programmers with two decades of experience that couldn't use a profiler and would dismiss clearly debugged issues, where they initially pointed fingers at the database and the network. It is quite easy to end up in such a state of incompetence - you don't do very demanding stuff or do the same stuff all over again for 20 years and then comes the advanced problem, you are under pressure, because the deadline has slipped again for a year and you are totally lost in the reflection hell you have created. I have other similar experiences with "professional" programming. Our CTO Pavel has a number of good war stories about static types, avoiding static types and problems created by OOP (classes are types too in my book) too.
Well, some libraries could use better documentation. So could Java, Python ... libraries. The point in Clojure is, you often can just read the whole function because it is like 10 lines of code or the whole library that often isn't that long either (200 lines of code isn't that uncommon). There are core developer on Slack basically every day, so you should be able to catch them and answer questions more or less quickly. And yes, I have had my fair share of problems with libraries too, you can check on Slack if you want - so I sat myself down and have rewritten the part that I needed more in line of our code. It is more robust as it has checks specific to our use case and we have one less dependency we would only use for 10% of its code.
In general, I think Clojure is a great language. It is very powerful and can be a chalange to wield without any kind of insightful guidance. Once you have crossed the initial steps though, you will probably surpass the productivity of most other languages even in a largish team.
I would be very surprised if the amount of Clojure/Clojurescript out there in production isn't several times larger than the amount of F#. Not trying to start a language war but with the exception of Jet which I don't think is around any more I can't recall a single large company using F#.
The most popular dynamic languages are all adding static typing though. Typescript became extremely popular very quickly, Python has been adding types annotations for a long time now, Ruby is adding them too, some team at Facebook is working on the same for Erlang. I've seen a few times Clojure users saying they don't need them, and considering Clojure has immutability, a strong REP and spec, I can understand that they don't feel the need. But Python, JavaScript, Ruby and even some Erlang/Elixir users think the opposite.
> I would be very surprised if the amount of Clojure/Clojurescript out there in production isn't several times larger than the amount of F#.
I think the same, but the thing is that I think the amount of Java for web apps is already several times larger than the amount of C# for web apps, which can skew things.
There were some optional type systems for Clojure but I cannot say how successful they are or were. I think the critical parts, e.g. APIs or code boundaries are specced out and that seems to be the recommended solution.
Btw. just that people are adding something doesn't mean that it is good or helping in general. It is great, Python has the optional type annotations precisely because they are optional - you can use them when you think you are better off doing the extra work.
I don't really agree. In Python for example, it's about making the implicit explicit. It's to make sure you don't use a function that only works on floats with ints. If you don't, you'll have a runtime exception, and it can be good idea to catch these errors at type checking time. You're already using types in dynamic languages, but they are implicit. Static typing makes the implicit explicit, and helps avoiding errors. If your type system is limited, it can make some things annoying that are easier in a dynamic language, I don't deny it.
> There were some optional type systems for Clojure but I cannot say how successful they are or were. I think the critical parts, e.g. APIs or code boundaries are specced out and that seems to be the recommended solution.
As I said before, I can understand that it's less necessary in Clojure than in Python or Ruby, because of things like immutability.
> Btw. just that people are adding something doesn't mean that it is good or helping in general.
It means precisely that though, if they're adding it it's because it brings value. Sure, your 50 line script probably doesn't need them, but your 10k app could benefit from them.
I think you're mistaken. It is my impression that the dynamic language advocates are, per person, more vocal than the static language advocates.
But as I said, that's my impression. And as you said, you think the opposite. That is, we both admit that we don't actually have data.
Anyone who does have actual data, feel free to supply it...
I really wish .NET Core came earlier and would have enticed Clojure to stay as a .NET language.
Clojure work great with JVM, it is very tightly integrated. Similarly ClojureScript and JavaScript, even though that is actually transpiling. With shadow-cljs, it really is quite integrated into the ecosystem.
First hand unfortunately I find the opposite is true - I have personally seen Clojure abandoned in a company and F# adopted instead in the same company albeit different parts. A rare case considering the nature of both langs. F#, to me really is like a statically typed Python that's got better performance, has better portable package management, and reads easier than OcAML/Haskell to newcomers with its "light" mode syntax. Having used Scala, Clojure F# feels like a simplification - it only takes in more expressiveness if it can stay simple. It also reads quite similar to most new breed lang's (e.g. for me when I look at Rust - if I squint many of the constructs look similar). In a month I've seen dynamic language only devs (e.g. JS, Ruby) with no static typing experience be productive in F# contributing advanced code - I've also seen Clojure abandoned in the same company with dev's perplexed with all the brackets, lost as the code scales, etc. Because it is simpler than Scala, Haskell, etc but does pretty much most of what these langs do (80%/20% rule) its a good gateway into functional programming IMO. With some of the new features in .NET 5 it can also be faster since it tends to run closer to the metal than Scala (i.e. no implicit wrapper types, rather use compile time polymorphism, stack allocation support, value types, etc when needed)
F# also has a REPL, and yes its simple but it does the job I argue with a lower learning curve. With one single script file you can load all dependent packages, and write your quick script straight from a naked .NET installation. Just `dotnet fsi script.fsx` or if you want to shebang the script that works too. May not be as pretty as Clojure but it has most of the bells and whistles and arguably much easier for a newbie to understand. There's also a ClojureScript like facility in Fable, heard good things but haven't used it personally. Being able to cut and paste a script in text (e.g. via Slack) to a colleague and it just works on their machine, libraries/packages restored whether they are on a Mac, Windows, Linux machine is pretty cool. All they need is .NET 5 installed.
On the teaching aspect using a JS dev (could be any lang) as an example - a module in F# is the same as a module in JS approximately - they contain functions that refer to other modules. Async blocks are similar to async/await and promises (! instead of await keyword). After that they get the hang of it pretty quickly. They even start to want to move away from their previous language as they realise things just work first time more often. They don't need to learn classes, OO, or all the frameworks typical of a C# project and all the "patterns". In other words it still feels concise like JS/Go/Ruby/etc to them. Functions chained to other functions in a readable syntax - that's it.
I've also seen F# dev's present F# code on slide decks to non technical people and it be well received - they didn't realize it was actual code. There's Twitter threads over the years on this exact scenario and it's what initially made me curious about the language. I can't imagine that happening with Clojure and its syntax of brackets, :require, classpath setup, etc etc.
Here are the top 5.
1. Python
2. Python
3. Python
4. Python
5. Python
If you REALLY can't use Python, then Rust or Go. If you are programing a game, the GDscript.Yeah, I know everyone hates on Go for its type system and because Rob Pike called it a systems language once (although the idea that OCaml is a systems language while Go isn't boggles the mind), but it's honestly so much more productive than any other language I've used. I also tried hard to like OCaml but the tooling was crumby and integrating libraries which used different standard libraries or async libraries or etc was painful. The ecosystem was also quite a lot smaller and important libraries were missing or low quality. While the Go community has its own problems, the OCaml community was positively toxic (if you have a problem for which there isn't a pat solution, then what you're trying to do is stupid and if it wasn't stupid then Jane Street would have solved it already).
While an ML type system is certainly nice to have, it turns out there are a lot of factors that matter more for practical software development, and if you're missing out on these fundamentals, the best type system in the world won't save you (and I posit that Go excels in these fundamentals even if it lacks an ML type system). I understand that this will not be a popular sentiment in a thread about F#.
> In my opinion there's space for a "Rust with GC", but every time I say this the OCaml and F# people come out of the woodwork to evangelize their languages but those languages miss the mark in many important respects.
I fully agree with this, Rust with a GC is what I've been looking for too. However as you said, F# and OCaml don't really fit the bill. Let's hope we can have something like that in the next 10 years!
> Let's hope we can have something like that in the next 10 years!
Agreed. :)
Dart is the language google is in a way selling, as the dev language for their new mobile platform flutter
Go, just happened, most available online material suggest that Go did really just happen
Rob pike have his taste, and build Go, in my opinion in the spirit of C, a pragmatic rather than theoretic effort
Go success, I think was not something that google really pushed for, it just happened because it seem many developer seem to prefer to use simpler languages, and deal with complexity "of using" a language, rather than learn a complex language and deal with the complexity "of learning" a language, developers are more engineers and craftsmen, rather than scientist
I'm not saying we should throw everything from Go away and all start programming in SML. I'm saying that people that worked on Go were too dogmatic to include pragmatic features that would have made it a better language. You can see this easily, from Rob Pike claiming that taxonomy is the least interesting kind of science or something like that, and thus a more useful type system is unnecessary. This is dogma.
Go didn't "just happen", Go had the support of Google to write a high quality and extensive standard library, and all the tooling around it. That takes a tremendous amount of time and money. SML or OCaml doesn't have that, so it's harder for them to compete. I assure you that if Go looked like a garbage collected Rust, while still having all the great tooling, the easy concurrency, the standard library and all that good stuff, its success would have been the same if not better.
Of course not every organization needs this, but many people will find B2B customers, regulators, due diligence people, etc. who are interested in the coverage metric as an indicator of quality. If you write the same tests as you would for another language, your line coverage will suck.
There's some nice stuff in F# that is entirely novel: my favourite feature is that if you omit passing ref values in a function call, they are added as multiple return values, a kind of dual to Currying.
Then there is the whole point if writing compilers should be considered systems programming.
Technically you don't need the former, you can pipe the FSX file directly into the fsharp interactive EXE that interprets them from notepad and console if you like.
It feels more like an introduction section than a whole article.
https://fsharpforfunandprofit.com/series/designing-with-type...
It's amazing
I didn't realize that was true. Long time coders or newbies?
Ocaml's standard library is amazing, and it has a great developer community, but at the end of the day Ocaml is its own thing. F# had virtually identical syntax, but put all of .NET at my fingertips. I was using it for UDFs in SQLServer, UIs with tables and plots, and a lot more. My brief flirtation with windows ended years ago, but F# remains one of the most positive parts of that experience.
Lost me. This is not true, by far.
It is therefor become an interesting alternative to TypeScript/Redux and Clojurescript/Reagent.
Also, Redux does make working with TypeScript slightly more difficult and verbose, at least in my experience, but I may just not be doing it correctly. The paradigm behind Redux and the Boilerplate that I end up with is what drives me to look for alternatives to Javascript and Typescript.
My main frustration with it is its lack of community. The Elixir forums are absolutely terrific; there is seemingly tons of knowledge sharing going on between passionate members of the community. The same with most other languages: if I Google how to solve a specific problem, an answer or an answer to an adjacent problem will pop up. That's true for Swift, Go, C#, Python...
It's not true for F#. F# seems to me almost like a dead language judging from the lack of relevant Google results, zero YouTube presence, no jobs where I live (northern Europe).
Is there a vibrant F# community somewhere online that I've missed?
I think in terms of actual community they have a discourse but it's dead because it's so hard to sign up for.
He has been the best PM for F# so far.
Naturally everyone is free to change careers and all the best to him.
Now F# needs another PM with the same passion.
> F# Is The Best Coding Language Today
Mmmhhh...
At least there is still C++/CLI behind it, in the set of tooling and .NET frameworks coming out of Redmond.
Anyway, the next .NET Conf focus will be on F#.
It is not managed by a secondary team.
With a few exceptions, every Visual Studio tool targeted for .NET development also does VB.NET.
The enterprise developers, those that Hanselmen calls dark matter developers, are more likely to use VB than F#, then leave and do something completely unrelated to work.
Maybe that isn't being strong, but it gets the job done.
Compared to that, F# is managed (by a peer of the C# group), advertised, and arrives everywhere.
Wish granted. https://imgur.com/a/PODd0Iv
And I find VS to be absolutely terrible in every aspect when compared to Qt Creator so the idea of using it for F# does not feel appealing at all.
So long as Microsoft makes sure F# is 100% supported in jupyter I see myself using it more and more to replace Python.
One huge item missing is a data frame library though. They started developing one last year but since then I have seen nothing.
Without dataframes it’s hard to convince myself to spend the time doing analysis. And Deedle is not up to par with pandas unfortunately.
> If you want to personally pick up a programming language in order to become a better coder in whatever other languages you use, F# is the best overall teaching/coding language you can find.
I can't speak to F# at all, but I can to Rust, in this regard. I haven't heard many people say this before - writing F# makes you a better programmer - but mostly that F# people are GSD types of people.
In contrast, I commonly hear other people talk about how dealing with Rust's strict compiler and clippy's lints help them improve their skills by rejecting bad code. In C, C++, Python, and JS, there's limited "guardrails" so most learning or improvement is mostly self-motivated. In Rust, the guardrails are strong that many people learn a thing or two about project structure, memory allocation, performance, semver, etc.
I just feel like this claim for F# is pretty strong, when the primary argument seems to boil down to "you can change your coding style over time." Does F# have as nearly as strict and helpful compiler as Rust - or any other language built-in tooling?
I've been wanting to play around with F# for years. Perhaps some day.
The classic chicken and egg problem
Maybe building your startup that needs 100 new people every year on F# is a bad idea, but for enterprise projects that don't move much, it seems a reasonable choice.
Hiring (or having others on the team who can work on the code) is a problem if you want to use a language in a company. (I mean, it's not if you just want to write a one-off program. It is if you're writing a program that is going to survive for a long time and be depended on by others.)
Rust feels like the closest thing to me in terms of overall practicality/ease of use.
I think F# does have a much stronger "in the browser" game. Yes, even a bit more than Rust, if you consider whole web applications and not just performance critical modules.
And some people and companies are extremely stuck in Dot.Net...
Sure I can write stuff in Go or Rust or Python but I don't see that any of those offer anything significantly better than .Net, including the support level, the quality of the IDE and even, God forbid, half-decent performance.
Sure I would choose another language for something that had to be super fast or perhaps headless but otherwise I would choose .Net every time.
Disclaimer, I have professionally used Java, PHP, C, C++ and C# but not Go or Rust.
IDEs for Python have improved a lot, and the more passionate Pythonists might fault C# for actually needing IDE tooling for being bearable...
I can see why you would prefer C# over PHP, C++ and Java for Web programming though.
F# came out well before Go and Rust and well in time to compete with Python's popularity. There were other factors that affected its adoption.
I think you should look again :)
You can do it in any language, FP languages can help enforce the distinction. For going even more functional, in FP languages that support it, free monads and effect systems allow you to define interpreters for effects and you can write code more or less like you would non-functionally, but the interpretation can be pure (say hardcoded results for a query) for tests, and impure for actually running. Basically fancy dependency injection, but for everything.
I could be wrong but I think an onion or clean architecture solves any issues you would have.
Depending on what you are used to, that might not be a huge problem, but the drop-off from the experience of working in C# or Java or even Python with modern tooling is stark.
I wish that there was an F# zealot or three working at JetBrains lobbying for better support in Resharper or Rider.
Great, we're back to this nonsense (also promoted by Haskellers) right off the bat. The best way to learn the language you use is to learn the language you use, period. If you want to be good at C, learn frickin' C. No, F# is not going to help.
Certainly if you just want to learn about "functional programming", yes, find a relatively completist FP language that that looks easy to learn (F#, maybe - Java, nope), and you'll find it easier to learn other functional-programming languages after that. It's also a good idea to learn new programming languages in general, just to expand your career potential and also make better decisions about what to use (if and when you are ever allowed that choice...).
Actually, if you want to learn one language that will make you better at all others? Assembly. Yeah. This is not because Assembly is The Greatest Thing Ever, but because you'll understand the magic behind the curtain a lot better, and be a lot more immune to the incessant nonsensical daily hype around programming languages. For bonus points, learn to write your own compiler/interpreter (but don't feel compelled).