Walmart is migrating the remaining F# code into Java
careers.walmart.com
careers.walmart.com
I was part of Jet.com before and during the acquisition, and the main reason I joined was because I was (and am) a big functional programming geek, had a fair bit of Haskell and Erlang experience, and F# seemed like a neat language.
It turned out that it absolutely was a neat language, and I consider the two years I was at Jet to be a fun highlight of my career. I got to see where functional programming shined in real-world distributed applications, where it didn't shine, and how it integrated with other libraries.
I quit in 2018 to work for Apple, stayed there for about two years, and went back to Walmart in 2021 for another year. In that time, I worked on the chatbot; one of the very last things that was still F# in the Walmart ecosystems. I had less fun the second time around (not really because of anything Walmart did and not because of F#), so I only stayed for about a year, but I still found some enjoyment doing professional functional programming in a pure-ish language.
It doesn't surprise me that they're changing to JVM stuff. Even when I was there, there was a lot of external pressure to move our stuff to Kotlin. We stayed with F# because of a reliance on the Microsoft Bot Framework, which was predominantly .NET, but once ChatGPT started getting traction I figured it was only a matter of time before they migrated to a Transformers model and rewrite it into JVM.
It makes me sad. F# is a language that I really do not think gets its fair shake. It's a language that really does push functional purity, but manages to still be pragmatic. I found the integration with the core .NET libraries to actually be very good, and even when I had to do OOP, F#'s implementation was exceptionally pleasant compared to C#. Honestly, if I had any say in running a business, I'd consider F# for at least a few of the services.
Generally speaking, F# was actually very fast, and had nice concurrency support, but there were times that wasn't the case.
For example, in 2016 I was part of the initiative to rewrite the ad feed. We had to read in several Kafka topics, do some joining on our end, and emit to a separate Kafka topic. This isn't terribly hard to write, but we were dealing on the order of about ~100gb of data being pushed into memory. This is hardly "big data" stuff, but it's enough to highlight some issues.
Specifically, the built F# persistent map structure was simply too slow to get the performance we wanted. I really like that structure, it's really handy and nice, but I ended up having to make heavy use of the ConcurrentDictionary that was built into .NET. This wasn't that hard or anything, but it made me a little sad that I had to move to a mutable store to get the performance I needed.
There was also the fact that the `async` monad, while generally very good and useful, had bizarre bottlenecks that were hard to measure. It was difficult to know when the async task was actually started, and when you tried to measure performance bottlenecks you were really only measuring the scheduler, not the actual performance. This isn't really F#'s fault, this is an issue with any kind of cooperative scheduling system, but occasionally to get the performance we needed we'd have to move to lower level threads instead of the pretty monadic stuff. Microsoft eventually released the Task monad which generally performed a bit better.
There were other things here and there; the Kafka client libraries for .NET simply aren't as good as the Java ones. Jet actually open-sourced their own (https://github.com/jet/kafunk) which did make it a bit more functional and nice, but it had performance issues as well, so a lot of us ended up using Confluent.
There were little annoyances specific to F# as well; there's no real concept of a monad transformer, so if you wanted to do something like, for example, combine an Option and an Async into generalized syntax, you'd have to write your own wrapper monad thing, which wasn't that hard but was sort of ad hoc.
The general rule of thumb was that the first draft of software, we would try and keep as functional and pretty. If that was too slow, we allowed mutation but only within a function. If that was too slow, we'd allow global mutation but only with thread-safe stuff.
Care to expand on this for the curious?
They contributed quite a bit of useful things to the ecosystem, and were one of the "F# companies that made-it".
Some of their projects live here: https://github.com/jet?language=f%23
An old HN thread on why they chose F# exists here: https://news.ycombinator.com/item?id=9971412 (though the link is broken, comments still exist).
As an F# enjoyer, it's not surprising that this happened. I've seen quite a few companies migrate to Java from various languages. Casting aside syntactical or language-feature niceties, there's just no substitution for the production-maturity of the Java ecosystem.
Plenty of open-source tested-at-scale libraries being put through their paces at large organizations taking in tons of traffic. Best-practices out-of-the-box adapter libraries for most infrastructure. First-party (actual first-party highest tier of coverage) libraries for communicating with the most common infrastructure (All of AWS, elasticsearch, kafka, cassandra, etc). Even with all of the open-source mindshare, most can have an extreme amount of information availability and support with the common core pieces like JUnit, Spring, Hibernate, and the accompanying set of libraries that usually join those. JFR is to my understanding still the only one of its kind.
I'm grateful for what everyone in the F# and dotnet community has done and continues to do, but even in dotnet (which is probably the closest competitor for production cloud web-services), you're spending a lot more time on writing and wiring up supporting libraries for things that the Java stack does for you out of the box. I prefer many small things in the dotnet world to the jvm world, but at the same time I can't deny that I'm much more able to focus on core business logic and concerns when working on a spring project than when I am on a .net 8 web project.
For what it’s worth, the 2023 stack overflow survey said 14% of professional programmers used Go vs 1% for F#. (Java at 30%)
And giving advice that's optimally defensible is the Highly Paid Consultant's actual job. You don't bring a consultant like that in when you're playing to win; you do it when you're playing to not lose.
I doubt this is really it. It's probably more about the size of the labour pool, and unfamiliarity with the language and functional programming that extends onboarding.
It's to the point where I don't even like to advertise that I like to work in functional languages around the office. Too much risk of being called in to be the hero when the last person who understood the code for some pilot project to try out Scala or Clojure that grew to become mission critical decides to leave the company.
That's a big part of why Scala and Kotlin code tends to avoid it.
https://dl.acm.org/doi/abs/10.1145/1297105.1297078
Ironically LINQ is something that was already present in Smalltalk collections, yet kind of lost in OOP languages until closures came to be.
The advice HN gave? Java is dead and he needed to reskill.
I don't have much familiarity with F# (although everything I've heard has been very positive), but your comment basically sums up why corporates use and will continue to use Java – the ecosystem is extremely mature and battle tested. While it might not be as fancy or fun to work with, you know you're in safe hands which is extremely important when you have billions of dollars resting on the stability and security of your software.
I'd even argue it's got little to do with the fact you have to spend time building things that comes out of the box with Java, and far more to do with the fact you can simply trust code that's been used by hundreds of fortune 500 orgs in production.
Edit: Okay, they know, I'm sorry :) Does not make it less sad and perhaps very unfortunate decision. Also, Hibernate sucks.
There's two kinds of Mono on Linux from what I understand...
The older one is packaged with a particular piece of security software, and the packages have more problems than I can count
edit: I got got! TIL that proper .NET on Linux exists. I'm more mad at Mono/this software now
It's security software - to be less vague, it's software made by Crowdstrike
Also, not liking what is now MIT FOSS stack does not make sense. It is the unified set of repositories going forward, with Mono currently serving exotic targets like WASM and being a part of dotnet/runtime. Completely not surprising for it is the most standard myopic response you usually hear from Linux communities (which, checks notes, are supposed to advocate for OSS?) the moment .NET is mentioned.
I mostly glue existing stuff together, not make new stuff. My frustration with .NET is dated, really due to Mono.
> which, checks notes, are supposed to advocate for OSS?
I'm not sure how much to unpack here; my complaints are more with what I was given than anything philosophical
Changing the underlining OS for 1000's of hosts is not a trivial task.
My title wasn't "architect", but it was "Staff Software Engineer" by the end. Does that qualify?
Where my heart lies aside, I also think it's rather dumb. My understanding of the system talked about in this job post is that it's quite mature and works very well, and my default stance for any rewrite is "don't be dumb, don't do it", and that would apply here.
It's too easy to run into a situation where the 'official' API supports Java/Python/Go as a first class citizen and the .NET library is a sad afterthought.
Let's look at general distributed messaging abstractions.
The most modern-featureful one for dotnet I know of is MassTransit: https://masstransit.io/documentation/concepts. You can see it supports a handful of queues and some interesting patterns.
Compare this to the list of features in Apache Camel: https://camel.apache.org/components/4.4.x/eips/enterprise-in...
Additionally, the _support_ of the libraries for common open-source (and closed-source infra) is usually vastly different:
- https://pulsar.apache.org/client-feature-matrix/
- Small features being first party like https://github.com/awslabs/amazon-sqs-java-extended-client-l... vs https://github.com/raol/amazon-sqs-net-extended-client-lib
- Missing features or those that lag behind: https://github.com/confluentinc/confluent-kafka-dotnet/issue...
- Usually manually wired and configured vs the spring boot "starter" pattern of having libraries that automatically do some of the manual setup work for you: https://github.com/spring-projects/spring-boot/blob/main/spr...
I wish more client library sets had the feature-matrix that the pulsar one does, because in practice most end up being the same: Java supports everything because it's either built in the same codebase or is the most used client and gets the most support, while the dotnet client codebase has many feature-requests or performance improvement issues, often leading to a "third-party client" being created.
We need a couple more Apache Struts and Log4J incidents for the public to realize there may be better technologies and ecosystems. Spring is very slow anyways.
As for Pulsar, there is a nice and optimized client (written in F#!) https://github.com/fsprojects/pulsar-client-dotnet
Avalonia being the most recent example.
Thus UNIX first shops rather focus on other ecosystems.
I recognize all the jargon here. None of it is exclusive to, or internal to Walmart, and the terms used are perfectly fine for the type of position.
F# is still pretty great though, I use it in many of my one-off personal projects. I think the jobs situation for it is still pretty poor in the US, but that seems true of any language outside the top 10. Even Rust devs, despite its popularity, apparently struggle to find jobs that use it. I suspect industry is very conservative with programming language adoption, maybe because there is a lot of risk in developing software in the first place. So there are winner-take-all dynamics in which ones get used in industry long term.
this self filters only the most committed and possibly eccentric programmers to keep using them, which again reinforces the loop. this is a shame because OOP, which has few of the theoretical and practical benefits of FP, is regularly taught
Of course when I took in person university courses we learned Java as the fundamental programming language.
I don't even really write very stateful or object oriented python anymore, and idk if anyone would really recommend that? That's been my experience though.
I don't really buy into the lack of talent/skill argument. Especially given that F# isn't exactly the most hardcore FP language and toolchain out there. I hire and onboard people from many kinds of background to a non-trivial Scala codebase. Even new grads coming from mostly Python notebooks do all right.
This is also supported by all modern OO languages going somewhat hybrid, as they adopt an increasing number of functional features.
If you're looking for an explanation as to why FP isn't more popular, I think it's mostly the fact that modern high-level languages have become good enough. And Go has proven that even an objectively bad language can succeed if the developer experience and productivity improve in other dimensions.
Most people working in niche langs arrived there looking for something better than the mainstream.
I would definitely have a lot of questions around the goals and motivations for the decisions behind the port. If the thinking is in the right place (we're making a good trade given our situation) I could get up for it, despite my bias toward functional-style code.
At my company I’ve asked that engineers proofread job descriptions so we don’t look stupid, but no, we still post for JAVA, NODE, and C SHARP.
Java
As
Viable
AlernativeI don't have experience with machine vision but here's an example of a speech2text library that integrates whisper.cpp in an idiomatic way: https://github.com/sandrohanea/whisper.net
There are many good community projects with code quality way higher than your average enterprise SDK with layers upon layers of abstractions and allocations. Finding them is the same as with most other languages like Rust or TS.
Looks like the position does not offer remote wfh unfortunately
I can't remember what they were called, they had some cool kubernetes (mesos?) stuff iirc.
The Jet.com CEO was almost immediately made the head of their digital transformation and took an end to end approach of digitizing everything from the website to their logistics and warehousing.
edit: https://corporate.walmart.com/news/2016/08/08/walmart-agrees...
they could've at least moved this codebase to rust. oh well. corporate's gonna corporate.
At the time (late 90's, early aughts) they were basically a sweat shop. I had one person working there tell me they got sued by one of their developers after said developer broke down their salary into hourly and were making under minimum wage due to all the overtime they were working.
The tech was pretty cool (back then, can't speak for today) but I would never work for them.