5 ms·
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 pro
by gmantom 10y ago
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.
- cm3 10y agoWhat concurrency models do you employ to saturate all cores, and how's GC behavior?
- gmantom 10y agoF# 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#.
- cm3 10y agoI 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?
- klibertp 10y agoFutures, for one (called Tasks I think). There are probably implementations of other models as well, but I never looked for them personally.
- ZenoArrow 10y agoIf you want to use an Erlang-style actors in F#, you can use Akka.NET: http://getakka.net http://getakka.net
- eulerfx234 10y agoI'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. Hopefully this helps!
- 10y ago
- strmpnk 10y agoI 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-and-parallel/ 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.
- Paradigma11 10y agoFor actor model: http://getakka.net/ http://getakka.net/ https://msdn.microsoft.com/visualfsharpdocs/conceptual/control.mailboxprocessor%5B%27msg%5D-class-%5Bfsharp%5D?f=255&MSPPError=-2147217396 https://msdn.microsoft.com/visualfsharpdocs/conceptual/contr... For channel/~process calculus: https://github.com/Hopac/Hopac/blob/master/Docs/Programming.md https://github.com/Hopac/Hopac/blob/master/Docs/Programming.... https://github.com/fsprojects/FSharp.Control.Reactive https://github.com/fsprojects/FSharp.Control.Reactive There is also the Async monad: https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual/asynchronous-workflows-%5Bfsharp%5D https://msdn.microsoft.com/en-us/visualfsharpdocs/conceptual... Ofcourse it is also possible to use standard .net stuff like the TPL https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110).aspx https://msdn.microsoft.com/en-us/library/dd537609(v=vs.110)....
- nickpeterson 10y agoI would assume you guys are making heavy use of the sustained low latency GC modes that got introduced in .net recently, or do you use the default?
- louthy 10y ago> Over 4 million customers already on jet and over 2200 cores That sounds like a lot of cores for such a small data-set. Are you able to expand a little more on why you need so much computing resource?
- gmantom 10y agoHave 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.
- louthy 10y agoI 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.
- joneholland 10y agoI work at Expedia. The hotel dynamic pricing engine alone is more than 2200 cores. And this is c++. It does handle a average of 200k requests per second though. Don't underestimate true cpu intensive work.
- partisan 10y agoDo tell... what tools/languages/frameworks/architectures do you use?
- joshlemer 10y agoI don't know if there's something wrong with jet.com right now, but every single category I go to, and every single search I do on the website, yields the "Sorry, your search did not match any products." page. Edit: Ok not every single category, but most. Pet store section works, but health care section for instance does not work.