Live data from Hacker News

How we secretly introduced Haskell and got away with it

tech.channable.com

121–130 of 188 posts

Re: How we secretly introduced Haskell and got away with it

#121

Earlier quoted context omitted.

Completely untrue. I'm not a Haskell evangelist (I appreciate it for what it is) but I thought I would at the very least point out that most of the documentation for basic data structures (i.e. Data.List[1]) not only are well-documented but have a link on the far-right side of the documentation site that directly shows you the source code and it's usually easy to tell what it's doing. Any developer should be able to…

I'm not a C evangelist, but I would point out that most documentation of standard C function is very detailed and its code is shown in its man page. Any developer should be able to grok that code and determine its safety. Mattaku...

They really should be able to.

Re: How we secretly introduced Haskell and got away with it

#122
post #4
post #2

The comparison between Stack and Python build tools is striking: > No messing around with virtualenvs and requirement files. Everybody builds with the same dependency versions. No more “works on my machine” and “did you install the latest requirements?”. I wonder why the Python ecosystem, which is much more mature, doesn't provide a build tool as delightful as Stack (which is less than 2 years old).

The whole "Do you have the dependencies and a Python env installed? Noß Then you can't run this script/program." was one of the main reasons I switched from Python to Rust, where cargo as the (very good) package manager comes with the language and, because Rust is a compiled language, you build all the dependencies into your executable you aren't dependent(heh.) on the user having installed a runtime that maybe or ma…

Indeed, Rust + Cargo and Haskell + Stack are very similar in this regard. Both have great package managers, and both produce a shippable executable with only a few dependencies on system libraries. One notable difference is that Stack downloads the compiler, whereas for Rust, every version of the language comes with a compiler and a Cargo. This ensures that you can check out a year-old commit and still build your project with Stack (modulo breaking changes in Stack, which so far I have not encountered), whereas for Rust the compiler version is not pinned.

Re: How we secretly introduced Haskell and got away with it

#123
> but if we could get it done, there would be no going back

The naïveté in this simple statement is so cute.

The list of concerns is also pretty naïve. The main problem you are going to encounter with this project is hiring. If you want to grow this project or if the main developers leave the company, I bet it will get rewritten in a different language in no time.

Re: How we secretly introduced Haskell and got away with it

#124
post #38

I'm just starting with Haskell and PureScript. So far I'm liking the latter better. It solves a few of their gripes with respect to strings, laziness and records, plus has a more granular/extendable effects system and cleans up the standard typeclass hierarchy. Also `head []` doesn't crash. Of course Haskell is more mature, has support for multithreading and STM, compiles to native, so it's more performant. But PureS…

> I wonder if PureScript would have been a better choice.

I have an aversion (based for a large part on prejudice) of things that involve Javascript and its ecosystem :)

I hear many good things about Purescript’s effect system, but I haven’t studied it in detail. This is definitely one of the areas where there is room for improvement in Haskell.

Regarding the type class hierarchy and head being partial, those weren’t really an issue in practice.

Re: How we secretly introduced Haskell and got away with it

#125

> No messing around with virtualenvs and requirement files. Everybody builds with the same dependency versions. No more “works on my machine” and “did you install the latest requirements?”. While this is nice, of course, I'm not sure that is outcome is unique to Haskell/Stack. It seems like you could accomplish a similar level of reproducibility by building a Docker image or bundling dependencies in some other way.

We are actually using Docker for generating the virtualenv that we ship and running tests now. The motivation for doing this is being able to control the environment; we can run tests and build a package on CI, and we can build the same package locally when CI is down. We don’t use Docker in production.

It is not clear to me how Docker solves the issue of pinning dependencies; I would rather have a file that states the exact version of every package to install, than an opaque blessed container image that has some versions installed, and I do want to have the versions used under source control. Generating the image would not be reproducible (in the sense of having the same Python files inside it) without pinning versions somewhere anyway, right? Or am I missing something obvious?

Re: How we secretly introduced Haskell and got away with it

#126
post #71

Earlier quoted context omitted.

Not really. Even then you'll get criticism that the teams were more skilled in one language, or that they didn't use the best practices of the other language. Also, even if you could manage to normalize for all these variables. You're still only going to be comparing the cost to create the project. You're never going to get someone to maintain the two projects side-by-side for years and compare the total maintenance…

Doing a rewrite in a different language and justifying language choice by a successful outcome of the rewrite is grasping at straws to justify the language change. Every time I've been involved in a rewrite, including ones using the same language before/after , the outcome has been good. The act of doing a full rewrite is where the benefit comes from, it's hard to separate that from a language switch.

It wasn't a rewrite. It was two separate web apps. Type safety categorically prevents classes of bugs that I've seen in real Javascript apps on multiple occasions. Haskell frontend apps that I worked on both before and after the JS app never suffered from that class of bug.

Re: How we secretly introduced Haskell and got away with it

#127
post #28

I'm the author of the post. I'll be happy to answer any of your questions :)

Thanks for the write up! In the beginning you mention that you ran into some bugs in the Python version that would have been caught by the Haskell type checker. Can you go into more detail about what those bugs were?

The most serious one is that we were submitting jobs (as json) that were missing a few metadata fields. In Python we passed around dictionaries, and even though we had json schema validation in place, this slipped through. In Haskell, we define a record type and the corresponding serializers. It is more code, but what you get is that invalid data cannot exist at runtime: it simply cannot be represented.

Also, a compiler refuses to compile your code if you make a typo in a field name.

Re: How we secretly introduced Haskell and got away with it

#128

Earlier quoted context omitted.

I can't imagine using a haskell-like language without laziness. It's what makes it possible to actually write small reusable functions. Tell me, have you ever used foldr in Purescript? It just doesn't lead to reusable logic there, so I have no idea why you would. But in Haskell, foldr is used everywhere. Laziness means that logic built with it is actually reusable.

> I can't imagine using a haskell-like language without laziness. It's what makes it possible to actually write small reusable functions. I don't understand your point. Why is laziness a requirement to write small reusable functions? Are you thinking about currying? OCaml is (relatively) similar to Haskell and is not lazy. Function currying does not require laziness.

There's a classic paper that answers this well: "Why Functional Programming Matters."

(Not a quick read, but not too huge, and it is a classic that is well worth reading sometime).

Re: How we secretly introduced Haskell and got away with it

#129
post #28

Earlier quoted context omitted.

Thanks for the write up! In the beginning you mention that you ran into some bugs in the Python version that would have been caught by the Haskell type checker. Can you go into more detail about what those bugs were?

I'm wondering if integrating MyPy into the build, or even using Cython for performance, could have helped.

We do actually use Mypy! I wrote about my experience with it here:

https://www.reddit.com/r/programming/comments/5x3hdd/channab...

Re: How we secretly introduced Haskell and got away with it

#130
post #6

In the 1990s I did research on the efficacy claims of object oriented programming versus procedural programming. This article bares a striking resemblance in the claims. Case study after case study showed that object oriented code had less bugs due to compilers catching bugs, etc. However, almost every study was similar to this report: it was a re-write from procedural to object-oriented. There exists strong evidence…

On the one hand, I have definitely had this experience - I rewrote a library three times, with large gains in performance, readability, reliability, etc, each time (but mostly on the third time, which was from scratch).

That said, isn't it also fair to say that with a better understanding of the requirements and problem, you may determine that a different language / paradigm is a better choice, in the same way you may decide a different class division is better?

Post reply on HN