Haskell in Production: Standard Chartered
serokell.io
serokell.io
This isn't always a quiet omission, like "we didn't end up using this" either. The best example is that a lot of people end up doing some significant work to disable lazy evaluation. Simon Peyton Jones is reported to have said that lazy evaluation has been kept "to keep us honest about side effects", i.e., that size effects become immediately painful with pervasive lazy evaluation. But in a production system, functional purity (no side-effects) is a means to an end, and lazy evaluation comes at a pretty extreme performance cost. Not everyone disables lazy evaluation in production Haskell, because not everyone thinks they need to for performance, but I've definitely heard about it enough times that it seems like a relevant pattern.
Production users of Haskell do seem to be happy about types, years into projects, so I'd take away that types are a benefit, but I do wonder if one might get those same benefits in another language without the problems which seem to crop up with Haskell, such as laziness causing performance issues, monadic complexity, and difficulty hiring.
Arbitrary side effects allowed by strict-by-default language without types constraining these ruin easeness of software development provided by Haskell.
When your Haskell program works and walks, add bangs and it will run. Lately I heard from my colleagues it will run even without bangs as ghc has improved.
Purity is Haskell's fundamental killer feature.
Other languages now also have quite sophisticated type systems, some of which can do specific checks beyond Haskell in certain areas (Rust's control flow analysis, TypeScript's ways to do "gradual" typing of JS), while Haskell can do more in general.
But only in Haskell can I look at a function's type and know it doesn't do any IO.
In development and production, this allows you to immediately skip over large amounts of code when debugging issues. Pure functions are a key reason why Haskell is good at correctness and maintainability.
For one very important example, consider software transactional memory. It has general side effects in the implementation behind the scenes, but inside transaction code they are not allowed.
What will C++ solution look like? stmconstexpr?
The C++ plan of attack probably is more syntax though. Maybe parameterise constexpr, constexpr<input_only_io> or similar.
My company codebase makes generous use of STM in Haskell. STM is the first concurrency solution I reach for in Haskell and I believe it's the idiomatic thing to do.
[1] https://haskell-cafe.haskell.narkive.com/t6LSdcoE/is-there-a...
Also, the rule of thumb is that you have to use STM, and it is mandatory, if there are more than one developer working on a project or if you have more than one module in your solo project.
Clojure's STM implementation is missing crucial combinators to combine different STM actions compared to Haskell (e.g. Haskell's `orElse`), which makes it much less useful. It's also more difficult to remember how to compose STM actions in a dynamically typed language, since you can't directly inspect the action at the REPL in the same way you would do with a simple data structure, which means those few Clojure codebases which use STM don't tend to use it pervasively, but instead confine it to a single place, because it gets too easy to make the equivalent of type errors in Haskell (but which are much more difficult to diagnose because they're not really type errors from the perspective of Clojure).
Or to put it another way, Haskell's STM implementation focuses on STM actions as first-class entities, which allows you to have all sorts of reusable actions scattered around your codebase or even stored in data structures (e.g. a list of actions). This is also why there are combinators for combining different STM actions (e.g. `orElse`) rather than just operators on transactional references.
This means you can build up a rich library of actions in different places throughout your codebase, then at the "very last moment" in your program you atomically combine different STM actions together (ensuring through atomicity that they all see a consistent view of the world).
Clojure's STM implementation on the other hand focuses exclusively on transactional references, which means it's difficult to build up a library of STM action "lego pieces" that you can reuse throughout your codebase. You can try to retrofit the same thing, but then you run into mismatches between different actions which is what I alluded to with type errors. This lack of composability is my view as to why STM has mostly withered in Clojure.
STM simplifies parallel execution of atomic consistent transactions significantly.
But I have seen any use for it, besides every GNU/Linux program having code linked in to call _ITM_registerTMCloneTable in case libitm is used.
Usually, one goes with a static parameterization of a monad. But [1] shows that it is possible to have a dynamic parameterization, where underlying types of a state can change.
[1] http://blog.sigfpe.com/2009/02/beyond-monads.html
This means that we can control state types and, borrowing from ST monad, we can control introduction of resources and their use. If certain free type variable is in state, we can use associated resource. Deletion of resource is a deletion of free variable from a state parameterization.
All this is from 2009 or so.
The borrow checker of Rust is a library in Haskell, if you patient enough.
The purity of Haskell made many these libraries possible, exactly because we can control different side effects.
So no one disables lazy evaluation.
It is strict evaluation that is selectively enabled.
I also have to say that focusing on the types in the compiler development was the right thing, but what was not right is not focusing on the automatic analysis and removal of thunk creation for lazy evaluation. There is a project now to implement GRIN (graph reductin intermediate notation) [1] which supports such analysis and GRIN is early 90-th.
[1] https://grin-compiler.github.io/
GRIN also automatically gives you many benefits of supercompilation.
We could have a much better Haskell code now if ghc decided to support several backends back then, not only STG/C--.
That's objectively incorrect.
Worth fighting over it? Zero snark intended.
True of vanilla Haskell, but from the article:
> So we ended up with Mu, a whole-program compiler to a bytecode representation with a small runtime interpreter... Mu has a strict runtime, which makes program performance easier to analyse and predict – but prevents us from just copy-pasting some Haskell libraries that rely crucially on lazy evaluation.
If S&C is to count as a Haskell success story (which it's often touted as), then I think it's fair to point out that it's a codebase where strict evaluation is used throughout.
As far as I know, the author of Mu is Lennart Augustsson, also author of Bluespec [1]. Bluespec compiles language that is very reminiscent of Haskell into a hardware gates. And Bluespec is relatively successful. Is there anything in the hardware gates' "evaluation model" that is related to the success of Bluespec.
>In this article of our Haskell in Production series, we interview José Pedro Magalhães from Standard Chartered – a multinational bank that has over 6 million lines of code written in their own dialect of Haskell called Mu.
In any case, regardless of the underlying motivation, it is certainly an interesting fact that one of the largest commercial Haskell(ish) codebases uses a strict variant of the language.
The Haskell codebase that made Mu possible is not strict.
>Mu has a strict runtime, which makes program performance easier to analyse and predict – but prevents us from just copy-pasting some Haskell libraries that rely crucially on lazy evaluation. [emphasis mine]
If Mu were an entirely different language then you wouldn't be able to copy-paste any Haskell libraries. See also e.g. here: https://www.quora.com/Why-did-Standard-Chartered-need-its-ow..., https://www.youtube.com/watch?v=hgOzYZDrXL0
The likeness of languages' syntaxes does not mean they are the same.
> Mu is a true Haskell dialect in that code written in Mu may be compiled with a Haskell compiler.
> [...]
> Their experience with strict semantics has been positive. Particularly useful is the ease of obtaining meaningful stack traces, tracking resource usage, […]
My point was that "if S&C is to count as a Haskell success story (which it's often touted as), then it's fair to point out that it's a codebase where eager evaluation is used throughout." Please note the 'if'. The article presents S&C's large Mu codebase as a Haskell success story. In this context it's perfectly fair to point out that Mu has a strict semantics.
If you want to insist that Mu is an 'entirely different' language to Haskell then that's fine. As with natural languages, there's no objective line to be drawn between 'different dialect' and 'different language'. However, anyone who holds to this view obviously cannot follow the article in presenting a large Mu codebase as an example of Haskell in production.
And then it proceeds to tell us that you can't tail recurse.
Mu is different language which uses Haskell ecosystem.
What I am interested in and what article does not tell is how big the actual Mu compiler is. I think it is in the hundreds of thousands of lines of code, 200K SLOC or more.
And it is still a big code base and it's use of Haskell is success.
This makes me wonder if this affects how code is typically written. Is it very elm like? Is composition more difficult? Is it very monomorphic?
I see some issues though.
Some niche languages enthusiasts can be very picky and reluctant to work on other languages, and would pick Haskell when a simple python script would be more appropriate.
People from Academia interested in Haskell may be good in PL theory, and writing compilers or static analysers, but may lack in other fields such as system programming, which incidentally is harder in Haskell too. So you also need to find devops, system guys and so on who can also be productive in Haskell, and those are more rare.
in my experience, these people also refuse to learn about any software engineering best practices as they are "for OO languages" and "not needed" in haskell
I've worked profesisonally in Haskell for 9 years now.
When working as a consultancy, whenever we hired for ourselves or our clients, we got 5x more applicants than we were looking for. Of those, around 80% got a hire recommendation (unfortunately we couldn't hire them all).
When hiring 1 role for our startup, we got 40 good applicants immediately, with a single post on Reddit.
In all cases we had the luxury of picking the best-fitting among many excellent engineers.
Maybe you'll face issues if you want to hire 100 people on the spot. But most companies don't have that problem.
> Simon Peyton Jones is reported to have said that lazy evaluation has been kept "to keep us honest about side effects"
Rather, one of the main benefits of laziness was to force purity and thereby to instigate the development of typed effects. By contrast, the reason that laziness has been "kept" is simply that switching to strictness now would break (almost) all Haskell programs!
> lazy evaluation comes at a pretty extreme performance cost
Not really. Haskell's implementation of laziness is very high performance and the compiler can easily determine when creating thunks is not necessary. The reason that lazy evaluation leads to performance problems is that programmers don't know how to use it correctly. Whether that's the fault of the language or the programmers is up for debate.
It's because it's objectively harder to reason about performance with lazy evaluation as performance becomes non-local. You can no longer reason about a function's performance just by looking at its body, instead you have to know the nature of the inputs passed to it (whether they're thunks or materialised values).
Each single uses of lazy evaluation also imposes a latency overhead as the thunk/value must be behind a pointer. Yes the compiler can remove unnecessary thunks, but that's "unnecessary" in the sense of "unnecessary given the semantics of the program", not "unnecessary given the problem the program's trying to solve". I.e. lazy by default will generally result in someone writing code that's lazier than necessary unless they're very careful with annotating to the compiler everywhere laziness isn't needed.
This is off-repeated, but has two interpretations. If you mean performance as in number of steps needed to reduce an expression, lazy evaluation is superior to strict evaluation. If you mean the indirection needed to access a thunk, well someone -- either the producer (strict) or the consumer (lazy) -- had to do that anyways. If GHC can determine that the demand for the value is strict, it won't generate the thunk in the first place. Instead it will provide a specialize calling convention via the worker/wrapper transform, which is standard. On the un-optimized case we still have dynamic pointer tagging (which is a transgression on the T of the STG machine) which serves as a tag to check whether we are dealing with a value or a thunk quickly. So if by non local performance you mean the indirection, modern GHC shows that is not true.
If you means that space leaks are a non-local property and they affect performance, well you are sort that right. But as with all programming, we have defensive patterns against that.
There are 2 types of space leaks: liveness leaks and strictness leaks. Only the first one are a non-local property, ie the appear as a consequence of the composition of different code pieces. But given the default purity of Haskell, those can only appear on long lived data references with are syntactically marked by:
- IORef, MVars, TVars
- get/put pairs over a state environment
So what you do is to specify in the types that values stored on those environments are to be evaluated before being stored, so references don't leak. I speak about this on this
https://epicandmonicisnotiso.blogspot.com/2023/04/how-to-avo...
and how to specify the a specific evaluation level on the types at here
https://epicandmonicisnotiso.blogspot.com/2023/04/presenting...
although that library has changed a lot to enforce the invariants.
If a client comes to me and says one of the parts of their application was slow, and I come back to them saying I lowered the number of reductions with zero change in the wall clock time, they'll fire me, and rightly so.
Here's a simple specific example. Take the Haskell expression [1..n], for some big n. There is no general answer to the question "what would be the performance implications of replacing [] with [1..n]" – it depends on the context of [].
In a strict language, you can say (roughly at least) that replacing [] with [1..n] will add at minimum a certain number of extra CPU cycles and a certain amount of additional allocation. This kind of reasoning is pretty rough and ready, but it is accurate enough to be useful for reasoning about performance in practice.
I note that Simon Peyton-Jones has said these exact words in a public talk:
"Laziness makes it much, much harder to reason about performance."
I think it's extremely unlikely that he's mistaken or confused on this point.
It's not at minimum, it's always the worst case cost of N in strict languages, whereas the lazy setting provides you with amortized complexity.
I think you might have thought I was saying that given a strict semantics it was somehow still possible that you wouldn't necessarily incur the full time and space penalty for constructing n elements (which of course is not the case).
I used to know Haskell to an “intermediate level”, but haven’t used it in years, but I am more familiar with “traditional” runtimes/compilers, like the JVM as a reference.
Also, laziness is a big part of why Haskell exists in the first place. "Strict Haskell" would arguably feel more like ML, Agda, Idris, etc. than (lazy) Haskell. In which case, just use one of those; they're also decent languages ;)
As someone with a lot of time spent experimenting with programming languages, I can't think of any that can be so excellent from a research/experimentation perspective that also share the real production usage that Haskell sees. Take for example Racket, an amazing and also extremely flexible research language. It's probably easier to get started with than Haskell, but has never seen the real world usage that I've seen from Haskell.
IIRC he wrote or said that lazy evaluation, was a mistake in hindsight.
Laziness in Haskell is a great way to write declarative code, you really are describing a concept rather that telling the computer what to do. That can lead to very clear and orderly source code.
Having said that, the drawbacks are significant, performance, memory usage, and debugging can all be a real pain. The last one sucks because it affects development of all kinds of programs, not just performance critical (and challenged) ones.
Shout out for PureScript, which is essentially a strictly evaluated Haskell that runs on the browser, servers, and PaaS.
Difficulty hiring on a small scale in my experience is complete BS, there are still many passionate users looking for professional gigs. Once that pool is exhausted, I think a company should probably look outside the language for people with some type of FP experience and expect language-specific training as part of onboarding, whether that’s worth the time and cost is entirely settled for me but certainly a topic for debate.
Anecdotally I can confirm this is true.
> Laziness in Haskell is a great way to write declarative code, you really are describing a concept rather that telling the computer what to do. That can lead to very clear and orderly source code.
100% agree.
> Having said that, the drawbacks are significant, performance, memory usage, and debugging can all be a real pain. The last one sucks because it affects development of all kinds of programs, not just performance critical (and challenged) ones.
I think this largely depends on domain. Then, it's not clear if the best tradeoff is to go fully strict or develop better intuition for lazy evaluation in many of those cases.
> Difficulty hiring on a small scale in my experience is complete BS
I have a theory this meme is repeated by people who don't know where to find the many functional programming candidates.
If your company needs to find candidates primarily on the basis of their familiarity with your particular tech stack, that is probably the wrong tech stack.
I disagree. I believe that most candidates are likely only interested in your salary, benefits, or other things not relevant to what your company does. A necessary state of affairs where worker rights and worker loyalty don't count for much in the face of the horribly named "right-to-work" laws.
Therefore a candidate that has a strong interest because of your tech stack is a positive where there wouldn't otherwise be one.
How is "being there for the mission and for the people" better than "being there for money and for tech stack"? The latter also has to do with people and missions, only the missions and the people are important and related to the candidate directly, and not through company owners' or hiring managers' goals (most likely motivated by prospects of monetary rewards too).
Tech stacks change; human stacks stay the same. Intellectual honesty isn't going to obsoleted by some shinier virtue in 5 years—and if a company needs to pivot, it's still going to be a right tool for the job.
Why should I value the subjective decision of some new engineering manager that decided the tech stack should change so they can pad their resume?
Even if I'm there for the mission, this would give me pause.
If I was there for the tech stack alone, I'd quickly be looking for a new job.
The central point you seem to be making is "hiring for people there for the mission means employees friendlier to company changes/pivots". This feels valid, however the tech stack could affect execution of the mission. Or a given person could just hold the opinion that tech stack affects execution of the mission.
I guess my counter-argument to that then is it's not such a straight-forward win.
However my views are that tech stacks and programming languages matter a lot more than most give them credit for. See:
It's not what programming languages do, it's what they shepherd you to https://nibblestew.blogspot.com/2020/03/its-not-what-program...
So it's easy for me to recoil to hearing "right tool for the job" cargo-culted without real arguments justifying the comment.
Circling back to the central point, I do think I would bias towards hiring people that seem "there for the mission". I believe many people would probably be just pretending though, so it's not that great of a postive signal imo.
However we may differ in that I don't think I'd heavily avoid hiring people "there for the tech stack" any more than I'd try (and fail) to avoid hiring people "there for the money".
Sadly, the mission is often money at nonprofits as well, because capitalism won't let you survive without it. But the "here for the mission" folks skew a lot more toward the "naive" side of the spectrum than the "lying" side. Again, exceptions exist.
It’s not the candidate’s job to be interested in your company. As a founder, leader, or even hiring manager it’s your job. Create a positive working environment. Get to know your employees and what their goals and interest are. Do your best to find ways to incorporate their interests into their work and align it with the company’s needs. Build rapport and treat them with respect, so when you must ask them to do tasks that don’t align with their long term goals they won’t resent you.
If you can use your tech stack to get desirable talent in the door, that’s excellent. Now it’s your job to retain them, keep them productive and happy.
Regarding your second statement, every job ad I’ve ever seen for software engineering contains a list of preferable languages and libraries, and I’ve never doubted that all things being equal, preference would be given to candidates with greater familiarity in that stack. Should it ever the primary criterion for hiring? Probably not.
It’s my job to do that for the right candidates. Positive working environment, caring about employee growth, long term goals—all these things you mention are extremely important, and they are what we should be competing on. If an engineer would forgo an opportunity that provides those just so they can compose monoids in the category of endofunctors, that’s unfortunate—but I am under no obligation to indulge them.
> Should it ever the primary criterion for hiring? Probably not.
I explicitly referred to when it’s the primary concern; we don’t disagree here.
In theory yes, in practice... not in my experience. Or at least, things are almost always fast enough in web backends.
> Not everyone disables lazy evaluation in production Haskell, because not everyone thinks they need to for performance, but I've definitely heard about it enough times that it seems like a relevant pattern.
Most people don't disable lazy evaluation in the way I think you mean it, but they use either BangPatterns selectively or StrictData.
Maybe there's widespread usage of `-XStrict` as well I don't know about.
Anecdotally I can say that trying to enable `-XStrict` in production caused performance issues that prevented us from trialing it further.
Laziness is frequently talked about as a negative, but it has big advantages in composition and code ordering like another reply talked about with regards to where bindings to enable truly top-down program design.
hah this is in many ways indirect proof that laziness-by-default is improving performance. It may even be that a rote translation to strict (which `-XStrict` does) is causing _time_ leaks, which are actually pervasive in production strict-by-default code.
I believe this is the case, but the times it saves you are invisble.
The occurences where it bites you though are very visible and made out to be a much bigger deal than they usually are.
In production Haskell I've seen it's typical you only need to understand how to use the common Maybe, Either, and IO monads. Maybe... sometimes... you need to create your own.
I actually think it's a bit of an anti-pattern, but this anti-pattern leads to a reality where the monadic complexity you alledge does not exist.
The other 10% is stacking the appropriate sequence of `FooBarT (BarBazT ... )` at the entry point to your program, which is admittedly pretty tedious.
In some workplaces, yes. However it's pretty tenable to use https://www.parsonsmatt.org/2018/03/22/three_layer_haskell_c... with no or few additional monads.
Alternatively, you can have just a few people that understand how to compose Monads and many others writing code within them.
I'm not sure if I think it's a best practice by any means, but it's a pattern I've seen that avoids having to include monad transformers in onboarding.
https://github.com/haskell-effectful/effectful
Here's a talk on it:
Rust. Rust is that language.
Rust's type system is good enough and close enough to Haskell without the footguns of other options (Java, C++, etc), with new paradigms that Haskell hasn't yet fully adopted (borrowing, etc) and consistency in build tooling, etc.
I hate to say it, but it's incredibly hard to suggest people run Haskell in production when Rust exists and you basically trade the difficulty of learning monads + mtl + ... for the difficulty of learning to live with the borrow checker.
Here is a good post on it:
Good enough for what?
> close enough to Haskell
Close enough for what?
> with new paradigms that Haskell hasn't yet fully adopted (borrowing, etc)
Honestly, I don't want to think about borrowing. For my gamedev/rendering tasks I have resource regions (as a library) and trust the runtime to do its thing.
Not until other languages raise their game. Nothing compares to Haskell for productivity and I've tried many different languages professionally over the years (including Haskell). But yes, reasoning about what happens operationally is the big problem.
100% agree.
> But yes, reasoning about what happens operationally is the big problem.
What types of issues do you experience?
In GHC Haskell, it can be difficult to predict the lifetime of heap objects and control when objects are not shared (optimisations may or not lift terms out of a local context).
This is surprising to me. I understand it making code harder to debug because timing/ordering is less predictable, but I would expect lazy evaluation to help with performance if anything ("the code doesnt rely on a specific 'when', so the compiler/runtime are free to re-arrange stuff for optimization")
What am I missing?
Perhaps they made the interviews more difficult since, or you got unlucky?
https://discourse.haskell.org/search?expanded=true&q=Standar...
Edit: Question out of ignorance for people that regularly program in Haskell in the industry: I want to believe that the language has nothing to do with this and is just their business logic, right?
Don't sleep on these finance companies, they're big development shops.
What do you think fintech companies do? (I'm not entirely sure either but I can potentially give a flavour of finance coding in general)
If you want to come up with prices for things then you'll need a bunch of mathematical optimization code, interpolation code etc, then an enormous chunk of market conventions (Quick! How do you calculate the yield to maturity for a Brazilian treasury bill).
Having established this you will then need to build a system for getting market data to the right places to be used - and probably snapping data for historical record too. This could be as simple as drinking from the Bloomberg firehose, or reading from an SFTP server in the morning (no really), or pulling in trading data from an exchange (https://www.eurex.com/ex-en/data/trading-files/efpi for example). It all gets very messy.
And now, if you are a bank rather than merely a player in a market you also probably have your fingers in many fiddly boring pies too (e.g. retail banking, mortgages stuff like that).
6 million sloc is indeed a fraction of what you’ll find in an investment bank. It’s also (I think) what makes it very interesting: an IB is a huge software system, with a mixture of extremely legacy (30y) and bleeding edge tech, and very strange human made rules.
6 million lines of Haskell maintained by around 40-50 engineers. Sounds like a lot of tech debt in the making.
Maybe the 6 million lines includes their fork of GHC?
Investment banks are extremely complex systems - 6 millions sloc, even in a very expressive language, make sense to me.
What’s harder to grasp is the real complexity of an IB - it took me years to get that. 30 years of random, non homogeneous software evolution, coupled with 30 years of funky human made rules in 200 countries. It’s going to be big and messy! And I really wish it were easier.
To some extent, it’s a bit like Unicode, or font rendering, or the tax code : on paper it’s just a bunch of rules, but for real, it’s big and complex.
But I'm currently at a very small fintech, and I've got about half a million lines of code checked out. There is a lot of copy-pasted code, but I also have nowhere near all the repositories checked out.
That's a single trading desk!
I work at a bank.
To answer your question - yes. The consumer website for the bank I work at was 9 million lines of code (at least as of 2019). A lot of it was bad code, some of it was dead code that was never deleted.
It's not as expressive as raw recursion since many uses of recursion are hard to express through combinators, albeit a great deal of research has been done in this area (look up recursion schemes).
The reason the moon is made of cheese is because it is made of yellow cheese.
> I’m the head of the Core Strats team at Standard Chartered Bank. Core Strats consists of over 40 developers using Haskell (well, actually Mu) as their main programming language.
wow - this team used to be 8-10 people? amazing to see its grown so much. our old head used to be https://donsbot.com/about/ . i have a pet theory that Don and gang ensured Haskell's viability by building so much stuff at SCB that SCB was kind of pot-committed to Haskell, thereby ensuring that they would keep investing and hiring until the end of SCB. Similar move was played by Cheng Lou over at Facebook, for Reason/Rescript. if you want to grow a programming language at a bigcorp, embed it in a biz critical application and you have job security for life
> Our core financial analytics library, Cortex, consists mostly of Mu/Haskell code (over 6.5 million lines) and forms the basis of our price and risk engine across all asset classes. It’s also pretty full-stack; we use it for everything, from server-side long-running batches handling millions of trades a day to front-end desktop graphical user interfaces.
yep i can attest to this - i will say that Mu was the best developer experience i've had for a long time. It comes with its own storage/persistence layer (simple KV store iirc) but the joy of not having to choose or maintain or scale was great. also the entire internal package ecosystem was searchable via function signature (via Neil Mitchell's Hoogle) and versioned daily (so if any regressions happened you could just jump back day by day - we didnt use git in my day). i also missed if there was a testing suite.
> We can seamlessly call C++ functions from Mu and vice-versa, and pure Mu functions can be used in Excel formulae via our Excel add-in
yeah this was used a bunch. however the traders rarely touched this code so it probably required a lot of support from the devs and probably some misunderstandings where had.
> What benefits do you see for using Haskell in banking and fintech areas? One great advantage is static typing..
no no no. correct me if i'm wrong but dont large fintechs like stanchart and jane st use functional languages because its so much better to parallelize for risk scenarios and complex option pricing?
> Does Standard Chartered have an in-house training program for upskilling Haskell developers? For training absolute beginners in Haskell we typically engage an external training partner.
ha. in my day i was just given Learn You A Haskell and told good luck!
SCB people reading along, i hope some of my FXO apps are still around. Coriolis, Corona, and i'm blanking on the main pricing one. 10 years wipes away a lot.
What does he mean by this?
1 - https://icfp21.sigplan.org/details/hiw-2021-papers/14/Haskel...
The original Mu compiler is not designed for separate compilation, our new version is, based on GHC's binary representation of compiled interfaces with unfoldings.
I'm not experienced enough to know, but it does feel like Haskell prioritizes "clever" code. Very beautiful, but hard to understand at a glance.
Testability does require some forethought but if your codebase always takes that into account then it's as easy as other languages.
I would argue that "Can people understand a unit of code without experience in that language/domain" is valuable, even if not the _most_ valuable aspect of a language. I also think dismissing this desire is usually an act of gatekeeping. "_I_ understand it so it's fine."
There are ways to write quick n dirty Haskell. Actually a super-power of Haskell is how easy it is to refactor from "quick n dirty" to "reasonable quality" without introducing defects.
I call haskell "the language of maintainable spaghetti" in this spirit. It really is incredible how types can take 99% of the risk out of refactoring.
Indeed while I miss machine refactoring tools from Java, I've seen vanishingly few bugs result from manual refactoring in haskell.
wtf
A friend who works as a at risk manager at a major bank sometimes shares horror stories about the giant spreadsheet they have for some part of their holdings. They have disabled the "automatic recalculation" feature because it takes over 48 hours to recalculate everything. This is after running it through a special excel compiler to speed it up.
I just never... thought about writing a Haskell plugin for it. It makes sense! Better than using some other language. Functional for Excel makes sense.
I love hearing horror stories about small (and large!) governments and companies abusing and misusing Excel. https://sheetcast.com/articles/ten-memorable-excel-disasters
Does not use Haskell.
Is it just me or is this... weird?
> Mu has a strict runtime, which makes program performance easier to analyse and predict – but prevents us from just copy-pasting some Haskell libraries that rely crucially on lazy evaluation.
As they copy Haskell library code and only sometimes modify it, I would count it as Haskell code until they modify it.
You can confirm that parsers/tokenizers is ranked "best in class" here though:
- Consider Haskell - https://gilmi.me/blog/post/2020/04/28/consider-haskell
- Learn Haskell by building a blog generator - https://lhbg-book.link
Thats not a knock on Haskell either, I have a more bog standard job than it likes.
As far as I am aware GHC's collector is not as good as Java's.