Live data from Hacker News

A couple million lines of Haskell: Production engineering at Mercury

blog.haskell.org

161–170 of 249 posts

Re: A couple million lines of Haskell: Production engineering at Mercury

#161
post #157

The problem I have with functional programming is debugging. Or more precisely, I would say it is a strength of imperative programming, especially the procedural kind. In functional/declarative style, you generally describe how things should be, not how things are made, and you let the language piece everything together to get the expected result in the end. It is all well and good (and even better) if you did everyt…

My trick to debugging is to simply make every nontrivial piece of code return the same output for the same input. (The trivial pieces of code too!)

No other (mainstream) language comes close.

But what about situations where the code cannot be written in such a form (like shared memory concurrency)? I use transactions for that.

No other (mainstream) language comes close.

And that's without the low hanging fruit of no nulls, no implicit integer casts, etc.

It is absolutely true that debugging Haskell code is harder than debugging other languages. If you took away the bottom 90% of footguns, how could it not be?

Re: A couple million lines of Haskell: Production engineering at Mercury

#162
post #55
post #7

> Haskell gives you tools to encode these incantations in types so they cannot be forgotten. This is, for my money, the single most valuable thing the language offers a production engineering organization. Haskell is admittedly, probably the most powerful widely (or even somewhat widely) used language for doing this, but this general pattern works really well in Rust and TypeScript too and is one of my very favorite…

> works really well in Rust and TypeScript too And of course Rust and TypeScript were heavily influenced by Haskell... they just don't mention it and call things differently, to avoid the "monads are scary, I need to write a tutorial" effect. Though it's less about monads and more about things like type classes. Imitation is the sincerest form of flattery.

> heavily influenced by Haskell... they just don't mention it and call things differently

Rust wikipedia says otherwise

Re: A couple million lines of Haskell: Production engineering at Mercury

#163
post #59

Earlier quoted context omitted.

I agree that this can be nice when done right (Clojure), but null is a high price to pay for this convenience. I must admit I’ve never had this problem in application development. In fact, I do want to change my callers because strengthening the contract is an opportunity to simplify the callsites - they no longer have to handle the optionality. The change might carry some semantic meaning too, why are you getting x…

> I agree that this can be nice when done right (Clojure), I don't think Clojure has untagged union types like TypeScript or Scala. > but null is a high price to pay for this convenience. Why would it be? Untagged unions prevent null pointer errors just as much as option types do, only they don't have the discussed disadvantages of option types.

I was thinking about a general experience of working with null/nil. Clojure has nil punning which makes sense in the context of the language (lisp variant) and can be nice to work with.

The null is a high price to pay because eventually someone will make some type assertion somewhere in the TS codebase that will end up biting you. Sure, you can be diligent, but will every contributor during the lifetime of a project be?

Not sure about Scala, but I did see NullPointerException every so often, and what is the practical advice to handle them in Scala? It’s to use Option[T]

Re: A couple million lines of Haskell: Production engineering at Mercury

#164
post #85

Earlier quoted context omitted.

> I’ve been able to wire transfer money without having to worry it might disappear I thought that was the whole point of banks - does money randomly disappear when people do wire transfers?

Shockingly yes. Or at least it happened to me. Nat wanted to wire me $10k to fund Tensorfork, and all I had at the time was a crummy US Bank account. I spent over an hour on the phone with them trying to get a wire transfer number, and in the end the number they gave me was wrong. The money never showed up. That’s how I found Mercury. I was looking for a bank that wasn’t amateur hour. Once I had an account the money…

That's amazing to me. I've never sent more than £50 without sending £1 first and making sure it got there before sending the rest to an "existing recipient".

It seems obvious to me, if you send money to the wrong account, it's not your money anymore.

Re: A couple million lines of Haskell: Production engineering at Mercury

#165
post #147

I once saw a real world Haskell code (from a huge investment bank) - the abundance of single letter variable names and short cryptic function names was striking.

Half the time the function names are operators, so you end up with an explosion of typographical symbols that makes perl look like cobol. Not my favorite aspect of the Haskell ecosystem.

You forgot the 10 levels of precedence and the 3 associativity options for operators ;)

Re: A couple million lines of Haskell: Production engineering at Mercury

#166

Earlier quoted context omitted.

I'm not convinced it really works well in typescript. the lack of nominal types requires you to remember some pretty hacky incantations if you want something like a newtype wrapping a primitive type my experience is that ocaml is more powerful than rust for enforcing this sort of type safety, because you have gadts that give you more expressive power, and polymorphic variants and object types (record row types) that…

It really feels like we’re solving the wrong problem sometimes. If a bad type can crash your application, sure, type safety is one answer but I have to admit I like the erlang approach; if something unexpected happens crash the process (not os process, erlang process) which has a very small blast radius on a well architected system (maybe doesn’t even fail the individual request that caused it). I wish more languages…

When working on large, important software, crashing is not the worst thing that can happen; corrupting user data and/or allowing unauthorized access is.

The point of using the type system to do something like distinguish between sanitized and unsanitized strings is specifically to prevent these kinds of security breaches.

Erlang was designed for traditional telecom, where reliability of connections was the biggest factor, not security. I fail to see how Erlang’s approach can deal with the issue of security breaches or corrupted user data.

Re: A couple million lines of Haskell: Production engineering at Mercury

#167

Earlier quoted context omitted.

I'm not convinced it really works well in typescript. the lack of nominal types requires you to remember some pretty hacky incantations if you want something like a newtype wrapping a primitive type my experience is that ocaml is more powerful than rust for enforcing this sort of type safety, because you have gadts that give you more expressive power, and polymorphic variants and object types (record row types) that…

It really feels like we’re solving the wrong problem sometimes. If a bad type can crash your application, sure, type safety is one answer but I have to admit I like the erlang approach; if something unexpected happens crash the process (not os process, erlang process) which has a very small blast radius on a well architected system (maybe doesn’t even fail the individual request that caused it). I wish more languages…

>if something unexpected happens crash the process

There are some expectations where that's a reasonable response to a violation, but there are many expectations where the violation implies a bug elsewhere and crashing the process will do nothing to address that that wouldn’t have been better accomplished with stronger compile time checking.

Re: A couple million lines of Haskell: Production engineering at Mercury

#168

Earlier quoted context omitted.

“I’m not going to use Rust because I don’t like it” seems like what you’re saying, which is totally fine. Plenty of people, myself included, manage to write and enjoy writing general application code in Rust. You’re allowed to not get it, just like I’m allowed to dislike writing C++.

No. That is not what I am saying. I am saying there are contexts where you do not get value out of it and you can potentially decrease your productivity because it is more rigid. You have examples above if you want to read through. In no way I am saying it is useless. I just see niche uses for it compared to alternatives.

I read most of your comment as phrasing the things that make rust unique as being additional burdens relative to what you would prefer, which is fair, but often they are what I appreciate about the language. Explicit result types are a great example.

Rigidity is a trade off: it can make initial development slower but refactors significantly easier, just as an example.

I don’t think any of your examples show it to be niche. It operates well in most of the space where C++ is a good option, and a bit beyond that (embedded, firmware, but also higher level things where you want performance but don’t want to worry about memory safety).

Re: A couple million lines of Haskell: Production engineering at Mercury

#169
post #161
post #157

The problem I have with functional programming is debugging. Or more precisely, I would say it is a strength of imperative programming, especially the procedural kind. In functional/declarative style, you generally describe how things should be, not how things are made, and you let the language piece everything together to get the expected result in the end. It is all well and good (and even better) if you did everyt…

My trick to debugging is to simply make every nontrivial piece of code return the same output for the same input. (The trivial pieces of code too!) No other (mainstream) language comes close. But what about situations where the code cannot be written in such a form (like shared memory concurrency)? I use transactions for that. No other (mainstream) language comes close. And that's without the low hanging fruit of no…

Same output for same input is implicitly part of FP. (Not for OOP, due to mutation and side-effects.) I would think that when writing Haskell, one naturally always aims for same input same output.

Re: A couple million lines of Haskell: Production engineering at Mercury

#170

My bestie works at this company and looking from the outside they have a good engineering culture. I do think Haskell is the right tool for the job, and they are playing to it's strengths, but part of me wonders if a lot of their success is attributable to the place just being well run in general.

> but part of me wonders if a lot of their success is attributable to the place just being well run in general

That was my sense reading the article - that the author would be running a successful engineering org using any language really.

Post reply on HN