While I think F# is a great programming language. The article missed some good uses of it.
Specifically the article missed one of largest F# deployment, in production, in the world at this point. We use F# at Jet.com and it powers every part of our core business from our dynamic pricing algorithm to search and analytics.
Over 4 million customers already on jet and over 2200 cores on azure all running F# code.
Have you ever used Jet? Try it, add a few things to your cart then add a few more and see what happens to the prices of the previous items. There are millions of permutations being computed behind the scenes.
The system is computing prices all of the time based on many factors. Plus we have built everything in house from our warehouse management system and supply chain tools to order management and everything else.
That amount of compute encompasses QA, Dev environments and any experimental and R&D work we are doing.
Plus jet.com is trying to compete with Amazon so that means the system has to be ready for many million more users than there are currently shopping with us.
I haven't used Jet, no. I'm not trying to call you out, just wondered why it was so large. I have to deal with a similar amount of pricing complexity (actually, probably more complex than Jet) in my line of work, and we don't need anywhere near that amount of resource, but granted we don't have your numbers either, and our setup is much easier to silo groups of users - so probably not directly comparable.
My comment wasn't so much about languages and frameworks (we use both C# and F#), but pricing complexity. I'm in healthcare software, and the complexity of pricing is crazy.
We have a system that joins hospitals, primary and secondary care providers together. Each hospital might have it's own prices, as will their consultants, etc. Insurers have standard price lists, but some consultants and practices have direct deals with them, which can affect the price (and the creditor for the invoices), we also support rule-sets for modifying prices based on location, clinician, day of the week, availability, benefit maxima, credits, etc. We support the notion of inherited prices, where a standard template can be setup and then used as a basis for more bespoke plans etc. All of which can be manually overridden. If additional services are added then that can affect appointment lengths and costs. If the patient self-pays they may get different prices to what they would on their insurance.
Some of our customers do occupational health where they go out and get contracts with the big city firms to provide schemes for their employees. Each deal they get is different and negotiated to the nth degree, which can include various plans/tarrifs/credits, etc. Some services the patients can book themselves online, some can only be booked by their HR manager, some as follow-ups by clinicians, etc. Also rules around what can go on invoices, how billing items are grouped, who can see what (i.e. should an HR person see what services you've had etc.)
The additional complexity comes with matching that all up with efficient scheduling. We have some customers where they have appointments that involve up to 8 separate clinicians or resources; so they need to be scheduled in and priced without leaving massive gaps in the schedules. We also support call-centres that could see 1000s of practices and can query all of them. The end result looks very much like an airline booking model, but behind it all is a mass of complexity.
The combinatorial issues are large, and have definitely caused us some headaches over the years. So I fully understand how these systems can get very resource hungry. We're not in the same league as Expedia or Jet in terms of scale (although we hold more patient records than Jet has customers, if that means anything) - and as I mentioned it's relatively easy for us to silo groups of users, so I suspect some complexities just go away for us because we can filter down the potential results quite quickly, but still 2200 sounded like a lot - it was just a gut feeling. I don't understand how a shop selling a product can have difficulty calculating a price, but just as my customers have no idea of the complexity involved in calculating prices, I almost certainly don't understand the complexities that the team at Jet have to deal with.
The way we've dealt with it is to build massive data-sets of various static combinations, so if patient X on chargeband Y wants service Z then they'll be changed N. That does mean some large data updates when someone changes their pricing and rules; but it means doing less work live - although it can still be significant. This all runs on two 32 core servers.
I know healthcare insurance pricing has become the most insane invention of bureaucracy on the planet. That is why I can pay cash out of pocket and sometimes get an 85% discount. The providers don't have to chase their money from the insurance companies - private and government included.
C# for the core app, C# and F# for satellite services. Not sure on what you're asking re: platform. If you mean hosting? Then we roll our own servers in tier 4 data-centres. If you mean OS/framework: Windows Server/.NET
All our mobile stuff is thin web-layers that consume our core APIs, so it's all js. I started looking at WebSharper and FunScript for a more strongly-typed and robust web-development experience, but they're all a bit too 'awkward'.
I keep meaning to look into Elm as it appears to be a more thoughtful approach to functional programming on the client.
I avoid JS, not because I don't like it, but there are other choices. Then again, it's much easier to find JS devs than Elm devs.
I've played with Elm, but not made anything of note with it yet. The Elixir/Phoenix crowd are getting hopped up about it lately as a good fit for them.
Yeah that stood out to me too, since when do people boast about how much resources they consume?
That's 2k customers (not concurrents) per core, which is a terribly low rate. Even if they've only been running 1 month that's 1200 seconds (20 minutes!) of CPU time per customer, and it gets rapidly worse the longer you assume they've existed...
F# has fantastic concurrency support. Great support for Asynchronous operations and Multi Threading. Being a functional first language and immutable by default means most of the micro services are stateless and this means we can take advantage of concurrency like crazy and not worry too much about race conditions. I think functional languages in general make concurrency much easier not just F#.
GC on the other hand is very aggressive with all of the immutable data structures F# creates. GC in F# is very good, though, I think without good garbage collection you have a tough time in a functional world. Microsoft is especially interested in GC performance for .NET and they have explored memory dumps to improve GC so it performs well even under load and when used with F#.
I should have been more specific in the question. I'm used to Erlang and Haskell (GHC) concurrency primitives and frameworks. To reformulate: what concurrency models can you employ in F# that don't involve manually managing threads/processes?
I work with F# and have a lot of experience with Erlang (less so with GHC and it's lightweight green threading but I've heard good things about it).
F# inherits lots of .Net's primitives which at their core are thread pool based task scheduling with the usual optimized data structures you see from this world. While this might sound primitive, F# takes it further by providing very good functional libraries which abstract this away allowing lightweight asynchronous computations to be passed around as values (the type being Async<'a>).
Alone, this is pretty nice but it wouldn't feel as natural without computation expressions which are similar to Haskell's do-notation but with some generalizations and flexibility added in. This allows asynchronous code to look and feel first class. If you're curious I'd check out https://fsharpforfunandprofit.com/posts/concurrency-async-an... or check similar links on your search engine of choice.
Now, the story isn't complete. If you're comparing things to Erlang, there are also things like MailboxProcessor<'a> and such which allow other common patterns to be easily implemented. The type checking here is a nice bonus over some other approaches to message passing languages. The big minus of course is that it's still a traditional runtime. If you really want Erlang's isolated processes, it's hard to do that well outside of a runtime like BEAM. I also think F# could use better fault-tolerance primitives but I'm actively working on this with heavy influence from my work with Erlang.
I'm an engineer at Jet and hopefully I'll be able to answer your question. The concurrency model within F# is based on continuations. The type Async<'a> = (('a -> unit) -> unit) - its a function which accepts a callback to be notified when the async operation completes. The existing .NET ThreadPool is used to schedule these continuations across OS threads. It uses a trampoline to tame the stack. The ThreadPool itself is a fairly sophisticated piece of work, with scaling heuristics, work-stealing queues, etc. The ThreadPool interacts with the Windows IO completion port multiplexer for IO. We extend this primitive in a variety of ways, notably into an AsyncSeq<'a> which in Haskell terms is ListT Async - a linked list interleaved with Async. We use this for stream processing, sockets, fault tolerance, etc. Async is very similar to Haskell's IO monad, although the representations are a bit different.
However, both Async and IO are insufficient to represent disjunctions. To that end, another concurrency library that we use is Hopac. Hopac is an F# implementation of CML, with some differences. Hopac provides a notion of an alternative (called event in CML; think Haskel's Alternative typeclass if you relax the laws a bit) and synchronous channels (note that async channels are special cases of sync channels). Hopac's has experimental support for lawful MonadPlus as well (see transactional events in Haskell = IO + STM + CML).
Some things that we're heading towards next are generalizing STM to be a bit to be more like RCU (see relativistic Haskell). Additionally, we are experimenting with extending this to session types, but nothing in production yet.
F# also provides a MailboxProcessor, which is similar to an Erlang actor, however without explicit distribution support, so perhaps more of an "agent". We typically use this as a low-level concurrency primitive, rather than a full-blown programming model. Most of our services are compositions of various request/reply interactions, and the Async model above is a great fit for this. In fact, we've primitives centered around the notion of an arrow 'a -> Async<'b> (specialized to Async). These primitives provide support for fault tolerance, logging, tracing, etc.
All of this works well with the GC. Async does cause allocations of course, but this is a price we're more than willing to pay. We've shared some GC dumps with the designer of the .NET GC and she believes they are sensible for a functional language. Hopac took optimization to a greater extreme, reducing allocations where possible.
Another F# library of interest is MBrace. This takes the notion of Async and fits it with a scheduler that schedules across a cluster rather than an individual instance.
Async is similar to a Future (such as in Java), with the difference that Future produces a result once and caches it, whereas Async re-evaluates each time it is executed. It can be made to cache of course. A Future is more like a TPL Task, though IMO, Async provides a more predictable programming model.
Go has go-routines and channels. A go-routine is similar to Async. In essence, they are a notion of light-weigh thread. Note however that Hopac support for channels is far richer than that of Go.
> async channels are special cases of sync channels
You got it the other way around - synchronous is a special case of asynchronous, because any synchronous result or stream can be processed asynchronously, but for having guaranteed synchronous results you're adding restrictions. And going the other way, from async to sync is not possible without blocking threads, which is an error prone, platform specific hack. Take the possibility of blocking threads away and you'll notice the true nature of these models.
In CML/Hopac, async channels (buffers) are implemented in terms of sync channels - there is not async channel primitive built in. Synchronization is the essence of this model. When an operation is waiting on a matching communication through a channel, it is suspended, but no OS thread is blocked.
But yes, going from async to sync requires blocking, which is why CML/Hopac takes the approach of making sync the core primitive.
This is a really great case study, but I can't help but think some of the improvement comes from it being the second attempt at the project.
I'd really like to see some case studies going the other way: F# --> C# [or C++].
At the least, you could do C# --> C# [ie complete rewrite].
Any time you do a rewrite with more knowledge of what worked and what didn't, you'll have a better system.
So ultimately, the essay [like most] leaves the question: Is F# better? Or is it just that complete rewrites can provide substantial improvement?
From all I gathered about people that story was related to, it seems the F# project was done without looking at the C# implementation, on basis of same specifications.
If you were tasked to implement a project because first implementation failed, would you even read the first implementation or just base your work on the specification?
Oh good point -- it does say they were separate teams.
Should one read previous implementation? That's a difficult question. If you're worried about losing your perspective from seeing a single solution, then perhaps you're right that you shouldn't.
But it's possible that merely implementing it in a different [more functional] language would encourage sufficiently different patterns to allow you to keep perspective.
With all of this said, I am a huge fan of both C++ and Haskell. I had just had an internal realization that these stories might not be extracting the positive effect that a rewrite might have on a code base [even though, as you say, that is likely not relevant here].
I was an early adopter of F# (1.0) and promoted it pretty heavily in my previous job. We used it for some of our prediction code.
I've since left and move to the Linux world, but have become more involved with using OCaml. Both are great languages (probably my favorites) and that's after investigating Haskell for a while. F#/OCaml's ability to easily move between functional/procedural/OO worlds makes it super flexible.
> F#/OCaml's ability to easily move between functional/procedural/OO worlds makes it super flexible.
When I wrote the reference compiler for an intro to compiler class in OCaml, some of the teams who used Haskell asked me about my choice; I said that while most of the compiler was written in a nice FP style, it was nice to have imperative constructs in a few places to follow the techniques from a textbook without having to adapt them and making sure that I haven't changed the complexity.
We use it for satellite projects around our core C# app (the only reason the core isn't F# is legacy, so I created a C# library to get as close as possible when updating/refactoring [1]).
The toolset is pretty boring/standard though: VS2015 + TeamCity + in-house Nuget + Gitlab
ensure consistency of dependencies across repository (can't do that with so many packages.config files)
* easy to figure out outdated dependencies / update those with changes that are very easy to diff
* no need to battle with transitive dependencies
* several transitive dependencies resolution algorithm (max can be used to be as up-to-date as possible)
* ease support for multi platform targeting (it puts conditionals around the references, when you switch platform, it switches to correct assemblies without you having to do anything)
* will write/maintain binding redirects related to nuget packages for you (saves from many runtime errors)
* can generate include scripts for nuget packages if you do .csx or .fsx scripting
* many more things
the UI integration in VS is not as good but if you look at it, the UI is also part of the problem with Nuget (doesn't work on several solutions, doesn't really understand transitive dependencies, etc.).
You can migrate with single command line, and start improving from then on.
it is a worth to try. It is:
- fast,
- reliable,
- understands transitive dependencies,
- can manage them in groups (like build-deps, test-deps, doc-deps)
- can have http and github as a source.
Just one drawback - comparable not so good graphical UI in VS, but very good CLI, converts entire solution from nuget with just one command in terminal
We have an almost identical setup to yours. How do you manage the long build chains in team city with the number of nuget packages you have? It's something we are grappling with and are considering moving everything back into a single repo with no nuget packages as a result.
Our eco-system is wide rather than tall. We have a solution that is a general purpose set of libraries that most of our projects include, then our core app which is a 50+ project solution, and many satellite service solutions.
The satellite services communicate with each other through my LanguageExt.Process system which is a clustered actor-library, and so as long as the message formats stay the same they can be built and updated separately.
Each solution has a '<project name>.Dependencies' csproj included that contains all of the nu-get dependencies. It builds to ../bin, and then all of the projects in the solution add their dependencies from there. That means it's relatively easy to manage the dependencies for each solution.
There's a manual element of waiting for a project to build [on TeamCity] before updating the references in projects that depend on it, but on the whole it's not been too bad.
it is 'paket.references' file next to each proj file and a single 'paket.dependencies' at the root of the repository.
You can also integrate the restore part to msbuild so it works out of box from visual studio, msbuild, teamcity, whatever.
People prefer though to have separate restore packages step, the same way people prefer to use a better tool than raw msbuild to orchestrate build tasks (tool such as FAKE http://fsharp.github.io/FAKE/).
Thanks for that. So I assume from this that I could drop the Dependencies project that we're using for paket.dependencies. Would the auto-migrator deal with this do you think? I guess it seems like it would.
* get rid of the Dependencies project (it was a side effect of trying to cope with the pain of using raw nuget)
* add a paket.dependencies at the root of your repository listing all nugets used across the solutions
* next to each project, add a paket.references file with the names of the dependencies (only top level, you don't need to list transitive ones)
running the convert-from-nuget command should practically work out of the box if you don't have far out inconsistencies (which I believe you managed by reducing amount of packages.config files), but I'd recommend to do another round of sanitization similar to what I'm describing.
I think if you give it half a day of studying / using paket on a smaller repository, you'll figure out all the things you need to accomplish migration on a large scale repository, after which you'll be recouping benefits any time you need to adjust references in projects / add or update nuget packages.
All over the place. :) I'm busy writing a federated subscription resolution framework, and I was finding it difficult to maintain a coherent dependency graph with mutable data structures.
As far as I'm aware, the most popular F# tools for writing code are (from most to least popular): Visual Studio, Ionide (either using Atom or VS Code) and Emacs. I haven't seen that many people coding in F# using anything else, but I'm sure you'd find a few people using the usual suspects (Vim, Sublime Text, etc...).
Last I tried there were a couple of issues with autoindentation with the fsharp plugin for emacs, but they're well aware of the issue and have been working on it last I checked.
I'd like to use mainly emacs but I've noticed high delays in auto completions on certain type providers that don't exist in VS. Not sure what the issue is...
I'm running it in prod since last year and from the runtime perspective there are no issues.
Tooling is what sucks. MonoDevelop F# support is very unreliable. Basic refactoring, like rename, don't work correctly every time and I had to literally do git reset few times, after renaming, as it screw up multiple files.
Also, editor often has visual glitches where letters get corrupted and I have to reopen the file to get it back to normal. Not something I expect from such a long time maintained application.
However, it looks like Xamarin Studio 6.0 will be much better.
Alternative is Visual Studio Code with Ionide plugin, but I didn't use that beyond trying it once. Hopefully someone else can comment.
After my experience, it run smoothly on Linux. I followed the guide at http://www.monodevelop.com/ to install mono, then F#; monodevelop is also a good IDE but personally I use spacemacs with F# layer.
We have several solutions developed in F# over the past year or so that run exclusively on Linux. Mono 4.x has made it an a viable choice for running in production, but the dev experience is still lacking. We develop mostly on Windows with F# power tools plugin. You can find our open-source stuff at https://github.com/Prolucid
It works, although from what I recall the installation wasn't that easy. I think I had to checkout a specific tagged commit instead of the newest master, because the latter had a broken build. Probably works now, it was years ago :)
Im using it on linux, its pretty good in my opinion, im still learning, but packet and stuff like that seems to work fine. Im using it with emacs, so i dont really know how you will fare with other editors.
Just tried F# on https://www.codingame.com/games/puzzles
Don't really see the use case for me, but fun to try smthg new => "one new language a day keeps the boredom away"
That's an awesome website! I made it through the first three puzzles using F#. It's too bad that there's nothing like IntelliSense there, but you can use Visual Studio or www.tryfsharp.org for typing and CodinGame for testing. It looks neat, but might not be the best for learning a new language. You can see some clever solutions after solving a puzzle at least. How familiar are you with F# and functional programming?
I came across F# a couple of months ago. Very nice language! Short, expressive, no noise like declaring vars/types that can be easily inferred at compile time. |> is amazing. Tuples. 'match with'. Took a couple of weeks to get over the hump, but I never looked back since. Work related stuff is still C#, but tooling, prototyping etc I do in F# now. Highly recommend. Also made me to rediscover glorious past of OCaml/ML that went over my head at the time (like most things).
I only know Go well enough to comment on his comments, but he did not do a good job testing and reporting on it in his posts, ignoring basic recommendations about safety taught to all beginners. (Ignores err responses from functions and then later complains that things fail later, most particularly).
I would be cautious about drawing too many conclusions about languages he didn't end up picking; clearly he knows OCaml and Python well.
You should read the first two blog posts in detail. He didn't knew OCaml at all at the time, and answers your remark about Go directly in the second post.
I did read those. I think it comes down to speed on boot, which seems like a legit concern, and a matter of taste. To wit:
Should os.Getenv return an empty string or an error if the environment variable is not set? -- The answer to this depends on how unix-y you are, I suspect. We might disagree, but it's not wrong to say that you're going to do what bash does, which is, after all the fundamental place these are kept, and return an empty string. In particular, this is well documented in the API, regardless.
If I create an empty list, then marshal some uninspected text into it, and that marshal function fails but I don't check its error status, should my list be poisoned, or should it continue on as empty? -- The idiomatic answer to this is that you should check error status and remediate.
He would prefer that the program vomit when marshaling fails. Fine, but it was entirely his choice to code in this style, against go style guides. To then claim the compiler is 'unhelpful' later when he tries to read the list he declared is empty is blame shifting in my opinion.
I would guess he does not prefer in-line error checking and remediation as a pattern; that's totally fine, but it's annoying to read snark about it.
If you read more carefully, you would see he would prefer that the language would not allow him to ignore errors.
You say "The idiomatic answer to this is that you should check error status", yes, that's a Go design pattern, but nothing enforces that. In other languages, thanks to Option/Result types, this is enforced, hence his opinion.
Such kind of safety and security concerns should not be enforced by conventions.
I want to suggest looking at a language like Erlang/Elixir that didn't start out from corporate self-interest (i.e., was open-source from the get-go) but a rising functional tide floats all boats. (And besides, Elixir "borrowed" a few good ideas from F#.)
I've had nothing but good experiences during my forays into functional langs. Here's to a more functional, immutable, easily-concurrent, easily-unit-tested future
As commented by others, F# was part of Microsoft Research, and not taken up by MS or other corporations when it was started.
Erlang started out in Ericsson, a corporation. Elixir and LFE (Lisp Flavored Erlang) started out opensource and are still opensource.
The term 'corporate self-interest' seems misplaced here, with the parenthetical remark turning it into the antonym of 'open-source'. The term proprietary, commercial or close-sourced seem more neutral and correct.
Erlang started inhouse at Ericsson, like F# did at MS Research, except it was for a company's immediate business needs or 'self-interest' to program their telecomm switches.
Elixir grew out of one person's frustration with Ruby's concurrency (Jose Valim), and a desire to have what Erlang offered him along with the BEAM VM and OTP. It has Ruby-like syntax, Jose is a popular Rubyist, and great tooling along with some other functional structures Jose added that he thought were missing in Erlang. [2]
Pony is an OO, actor-based, open source language, yet it has a lot of corporate pickup from fintech and others, and it seems to be getting ready to shove Erlang/Elixir/LFE aside on concurrency and speed. It has fully-concurrent garbage collection that doesn't use the "poison pill" message approach to kill all actors.
The creator of Pony, Sylvan Clebsch, has one foot in academia, and the other in business. He has worked on fintech, milsims, and games. [3]
I agree with everything here except for the Pony promotion because after working on OO codebases for 15 years now, I am
mostly convinced that OO has fundamental design flaws, at least when it comes to the long-term scalability and maintainability of codebases.
Unfortunately it is difficult to "prove" this definitively currently, until someone comes up with a "complexity polynomial metric over time" for code, except to talk to old programmers like myself (44) who have done this for a long while and gotten disillusioned due to all the time spent repairing OO complexity/tech debt bugs, and have become entranced by functional langs and the way they avoid inheritance, use immutable values and are super careful with state, all of which contributes to better long term code life
Fortunately I'm not the only old OO guy proclaiming this, I have John Carmack on my side:
"My pragmatic summary: A large fraction of the flaws in software development are due to programmers not fully understanding all the possible states their code may execute in. In a multithreaded environment, the lack of understanding and the resulting problems are greatly amplified, almost to the point of panic if you are paying attention. Programming in a functional style makes the state presented to your code explicit, which makes it much easier to reason about, and, in a completely pure system, makes thread race conditions impossible."
"No matter what language you work in, programming in a functional style provides benefits. You should do it whenever it is convenient, and you should think hard about the decision when it isn't convenient."
I heartily agree with what you have said. It is the reason I am not really biting at Pony. Maybe if I needed everything else it offered, or fully understood everything else it offered?
The problem I see now is that the entire functional domain is so spread out - Clojure, F#, OCaml, Haskell, Idris, Erlang/Elixir/LFE, and even the APL/J/K/Q crowd and Java's attempt to go functional. I'm not complaining about the number of functional languages to choose from, which is good. It's whether there will be enough critical mass in any one of the functional languages given a new non-functional language popping up every week. I don't know.
Now that MS has opensourced so much, and Xamarin's stuff is free, F# is looking better to me (again).
I also find myself dropping to C. C was my third language (after 6502 assembly and CPM Basic). Haskell/Idris/Elm are my toys of the year. I never fully dove into Haskell, but the concise, readable and very mathematical syntax agrees with my sensibilities.
Old! I'm 52, but I didn't stay with programming for a living, so my age doesn't reflect my programming experience. I did start with a CPM PET in 1978/79, but then went on years later to do other things.
F# comes from Microsoft Research and was notoriously ignored by the corporate side for years (and still is to some extent). So I'm not sure F# has really ever been a project of Microsoft corporate interest, and now there is the F# Foundation which has many non-MSFT people and companies involved.
While I like Erlang a lot, I'd say that Ericsson still has quite a bit of corporate control and interest. It's not always a bad thing to have companies involved in the success and advancement of technology.
I've looked at it and it looks nice indeed. Having BEAM underneath is a big plus.
However, dynamic typing turned me off. Whole my life I'm working with statically typed languages and heavilly rellying on compiler / type system to catch my mistakes / guide my design. Hard to give up on that.
F# is similar but if you're using features like polymorphic variants, functors, or first class modules, it might take more effort. In terms of package management, I'd check out paket. It wraps up the otherwise very quirky nuget system that .Net uses and also supports things like source dependencies.
This was a bit of a surprise to me. Is there a disproportionate amount of people in Finance using F# compared to other technologies? Any particular reason for that if the answer is yes?
I think the article is spammy and has a clickbait title. Unfortunately reading and addressing the actual article on Hacker News is old-fashioned.
StackOverflow surveys, while interesting, are probably meaningless because they suffer from selection bias. Even so, I would guess that F# developers are very well paid, like other developers of FP languages, but it's probably not because they work with F#. The causality is likely reversed - good developers that tend to be well paid are also the kind of people naturally interested in expanding their skill set, hence interested in FP languages.
Nothing screams spam more than usage of a hot keyword like "functional programming" while leaving hints that you don't understand what you're talking about. I would expect an article that reads like a marketing brochure to at least make a short attempt at explaining what functional programming is. If you copy/paste testimonials from fsharp.org/testimonials, you could also copy/paste from Wikipedia. But then, their own course named "Functional Programming" doesn't seem to have anything to do with actual functional programming: https://fsharp.tv/courses/functional-programming/
Functional programming is a broad term that at its core describes languages that allow you to pass functions around as values to other functions.
In other words, when using a function the parameters of that function can be defined as other functions instead of needing to be precalculated variables or constants.
That's basically all that links functional programming languages, all other language design decisions can vary.
Most OO languages can do this now, and they wouldn't be classed as functional languages. I know this is always a sticky subject, but for me I prefer to think of functional languages as 'expression oriented' rather than 'statement oriented'.
F# is a functional first language, yes, C# with Func<> can do many things, but functional code in F# is just smooth and easy, unlike C#, where you have to put up with lot of noise.
I haven't mentioned or was making any points about F# or C#; I was commenting on what appears to be your definition of a functional language, that is "Functional programming is a broad term that at its core describes languages that allow you to pass functions around as values to other functions".
Even if that meant something in the past, it really isn't a useful definition any more, because pretty much all languages do this. That's why I offered my alternative description. Even if it too has flaws, I think it's a more meaningful description.
"C# (pronounced as see sharp) is a multi-paradigm programming language encompassing strong typing, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines."
What makes a language 'functional' is first-class functions (i.e. functions that can be treated as values, which is what I was referring to in my earlier post).
As sremani said, F# is 'functional first', in the sense that the language is designed to make functional algorithms straightforward to express. You can write C# in a functional way too, but there's less syntactic sugar for this style of programming.
First paragraph on the Wikipedia page for Functional Programming [1]:
"In computer science, functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions[1] or declarations[2] instead of statements."
Pure functions, i.e. that are 1) idempotent 2) have all their arguments passed in 3) cause no side effects as a by product of evaluating the function are fundamental to functional programming.
But not fundamental to the definition of a functional language. F# isn't pure, but most would call it a functional language - so purity is surely not 'fundamental' - in fact most functional languages aren't pure.
That's why I prefer to stick to the 'expression oriented' concept, it seems to be the thing that captures most, if not all, functional languages. But I guess just like there are plenty of people that wouldn't call Java OO (and would prefer the Alan Kay definition), there are plenty that will disagree with any definition of 'functional'
(preparing for the inevitable 'functional first' comment).
I'm not an expert on this subject (have only dabbled in a few FP languages over the years), but what I've read in various sources leads me to think that the term "functional programming" itself is not very well-defined, or, to put it another way, different people may have different definitions of it, each including and excluding various language features or capabilities. Is that right? Any experts care to comment?
Yes, but you could say the same about "object-oriented programming" (is it about inheritance? message passing? N/A?) and even something as well-defined as "pass by reference" (many people apply this term to Java, many others think that is completely wrong).
Ultimately, we have to live in a world where words are kind of ambiguous, but I think we should try to avoid useless definitions. The definition where "a functional programming language is one that can pass functions around" is extremely useless, because it applies to every modern programming language including C and C++. Whatever you want the term to mean, it shouldn't be that, because that distinguishes nothing.
> "Whatever you want the term to mean, it shouldn't be that, because that distinguishes nothing."
It's not extremely useless when you consider most programming languages cover multiple PL paradigms.
Functional languages are a spectrum. On one end you have pure functional languages like Haskell where you're forced to use functional algorithms for all computation, but there are languages in the middle of that spectrum like C# which support a bunch of functional language constructs (take a look here for a selection: http://www.codeaddiction.net/articles/13/lambda-expressions-... ) even if they aren't purely functional.
My argument is, any definition of functional programming that ignores the mid part of the spectrum is useless, as it ignores that most languages do not strictly follow a single approach like Haskell but allow you to adapt to different styles (i.e. most programming languages are multi-paradigm). Even F# and Ocaml allow you to write in an imperative style if you so choose, and many people would class them as 'functional' languages.
Yes, but it doesn't bolster your argument as much as you think. The state monad in Haskell offers a more principled (some say annoying) way of dealing with mutation.
IORef's if I recall correctly offer the type of mutation similar to what is colloquially thought of as mutation.
These add to your argument a bit, but they're usually seen more of a last resort
Sort of. My very opinionated point of view would be that Haskell demonstrates that the functional paradigm is the correct setting for the imperative style.
I think the title can be alleged mostly to the misconception which is prevalent at Microsoft since F# was introduced as a commercial product (before it used to be a Microsoft Research product).
Maybe you are unaware of that?
F# is a pretty good general purpose programming language and that is what the title and article tries to promote (albeit it doesn't give enough and diversified examples).
F# is also a reasonably easy programming language which puts emphasis first on "functional programming" (which you frame as hot keyword, I doubt the language was made to fill a hot keyword).
I don't know about the for pay contents of fsharp.tv, but I gather they might be introductory and try to bring understanding of "functional programming" aspects to an audience which isn't versed in it, it is sure good for them if "functional programming" is a hot keyword and people are looking for training material to pickup that language, but I wouldn't dismiss that as being spammy.
That is confusing/questionable wording, but it can still be logically consistent. Here's an analogy: Football (soccer) is the most popular sport worldwide, but it is not among the top sports in the U.S.
Not necessarily. Bear in mind this based on survey results from Stack Overflow and the sizes for some of the categories are quite small.
For example. Dart is the second highest paid language globally but doesn't even figure in the top paying US (maybe because too few US Dart devs responded).
Programming languages are hyped now worse than cars :
"From code to colossal: Waagner-Biro recently used F# to construct the dome of the Louvre Abu Dhabi museum"
They used X programming language to build the dome of a museum ? Wowwww...
Specifically the article missed one of largest F# deployment, in production, in the world at this point. We use F# at Jet.com and it powers every part of our core business from our dynamic pricing algorithm to search and analytics.
Over 4 million customers already on jet and over 2200 cores on azure all running F# code.