Live data from Hacker News

Concurrency in Haskell: Fast, Simple, Correct

bitbashing.io

101–110 of 129 posts

Re: Concurrency in Haskell: Fast, Simple, Correct

#101
post #52

Earlier quoted context omitted.

This why I haven't fully embraced Rust yet. Whenever I ask about safely mutating shared state (see sibling comment), I'm met with silence, or some comment like: Rust guarantees that you aren't mutating shared state.

I'm surprised you say this. The core type system guarantees is that there is no aliasing while mutating, and no mutation while it is aliased. You get single writer multiple reader for free without overhead. If you want multiple writers, you can always use the Arc container and use the built-in lock.

>> or some comment like: Rust guarantees that you aren't mutating shared state.

> The core type system guarantees that there is no [sharing] while mutating, and no mutation while [sharing]

Re: Concurrency in Haskell: Fast, Simple, Correct

#103

Earlier quoted context omitted.

What exactly do you write, where your Python+C is faster than Nim which compiles to optimized C?

Generating millions of rows of synthetic data for testing RDBMS. Tbf, I didn't spend much time trying to optimize the Nim code once I got a working PoC, so it's entirely possible that I could've made it faster.

You may no longer be interested in this kind of thing, but if you are there might be some ideas of note over at https://github.com/c-blake/nio/blob/main/db-bench.md (in particular the demo/gbyGen.nim program).

Re: Concurrency in Haskell: Fast, Simple, Correct

#104
post #100

Earlier quoted context omitted.

There's no time like the present. Feel free to reach out if I can help you along your journey

Not the person you're replying to, but I'll bite: I've written low thousands of lines of Haskell. Similar to mikojan, I love Haskell in theory, but ended up not enjoying it as much in practice. 1. The multitude of string-y types. I end up converting between String, Text, Lazy Text, ByteString, Lazy ByteString, and I forget what else. Each library wants me to pass in a specific string type, and each other library retu…

I'm not going to sell you on anything. All of the things you've mentioned are true. Loosely, the multitude of string types and the state of the standard library come from the same place: the language is 30+ years old! There are many warts to be found.

However, if you decide to start learning, the path is hard, especially if you come from a non-computer-science background like me. I attempted to learn Haskell twice; I bounced off the first time, quite hard, and didn't try again for years.

What worked for me is a combination of two things:

* Having a goal in mind, that has nothing with the choice of language. For me, it was building a personal website

* The book Haskell Programming from First Principles [0]

and if you have more questions, reach out.

[0]: https://haskellbook.com/

Re: Concurrency in Haskell: Fast, Simple, Correct

#105
post #79
post #56

Earlier quoted context omitted.

Yes. And immutable data structures. When data is immutable, it can be freely shared. Changes to the data essentially uses copy-on-write. And it only writes the delta change, since you don't need a deep copy due to immutability. Add that the garbage collectors of Haskell and Erlang are designed to work with a high allocation rate and have 0 cost for dead data, and this is much faster than what people think. The way yo…

Web servers handling lots of small requests are actually pretty easy to garbage collect to: you just delete all the data at the end of the request. Either you have a specialised GC that works like this, or probably a good general generational GC can pick up on this pattern on its own.

Or you do as Erlang's BEAM VM: each thread has it's own memory area which is GC'ed individually. This means upon request termination, you just terminate the thread and the memory is reclaimed with no need for a GC.

Re: Concurrency in Haskell: Fast, Simple, Correct

#106

I’m not familiar with Haskell concurrency. The combination of green threads and large memory allocations due to immutable data structures sounds like it would be hard to implement a web server handling 10k+ concurrent requests on commodity hardware? Btw. too bad author talks about microsecond guarantees usage but does not provide a link, that would be interesting reading.

It doesn't actually have "large memory allocations" due to immutable data structures. This is a meme that isn't true. Immutable data structures, especially at small scale, do not have huge performance penalties. You don't copy the entire structure over and over...you copy the O(log n) spine.

Haskell's GC is also fast when you are mostly generating garbage, which is inherently true for web server handlers.

Re: Concurrency in Haskell: Fast, Simple, Correct

#107
post #78

Earlier quoted context omitted.

> sounds like it would be hard to implement a web server handling 10k+ concurrent requests on commodity hardware? In practice, it is not. The canonical Haskell compiler, GHC, is excellent at transforming operations on immutable data, as Haskell programs are written, into efficient mutations, at the runtime level. Also, since web development is quite popular in the Haskell community, lots of people have spent many hou…

> The canonical Haskell compiler, GHC, is excellent at transforming operations on immutable data, as Haskell programs are written, into efficient mutations, at the runtime level. Yes, at the level of native machine code and memory cells, there's not that much of a difference between immutability + garbage collection, and higher level source code that mutates. Thanks to GC you are going to overwrite the same memory lo…

Programmers for some reason really don't understand that generational garbage collection provides locality. I am really surprised how often I see C/C++/Rust types not understand this.

Re: Concurrency in Haskell: Fast, Simple, Correct

#108
post #86

My favourite thing about Haskell concurrency is that there are no colored functions [0]. Writing code in IO, or Async, or the next big thing (asychronous higher-order effect system of the future??), doesn't require language support like Python or Rust. The one construct that unlocks this lack of colored functions, STM, did require runtime support (as opposed to language support), which at least is transparent to down…

Coloured functions are a feature - not a bug, Haskell is full of them, and they are exactly what make STM safe in Haskell, but abandonware in other languages which have tried. 2. The way you call a function depends on its color. ` >=` vs `=` 3. You can only call a red function from within another red function. This should sound pretty familiar! You can only call an IO function from within another IO function. STM in…

It is a shame that the people you are answering is being downvoted, I also understand the importance of coloring functions, but look at the examples that person put, python and rust. In those, executing a colored function (at least the async related ones) propagates up to the top of the program, that is a cost that we have to interiorize, but I would be lying if I told you I wouldn't he happy with such behavior. I do a lot of js/ts and I would love to just be able to "inline" await without making my current scope recursively to the top of the program like it can be done with F# with the Async.StartAsTask operation.

Re: Concurrency in Haskell: Fast, Simple, Correct

#109

Earlier quoted context omitted.

No reason. OC probably thinks that immutable data structures are always copied when being operated on.

Yes indeed, unless you use ropes or other specialised structures

Well luckily, Haskell is full of said "specialized structures."

containers and unordered-containers handle most of your needs and they only copy their trees' spines (O log n) on update.

Re: Concurrency in Haskell: Fast, Simple, Correct

#110
post #97

Earlier quoted context omitted.

My impression at least watching chatter over the last several years isn’t that it has a bad reputation but rather that people haven’t found a need for it, atoms are good enough for vast bulk of shared mutable state. Heck even Datomic, an actual bona fide database, doesn’t need STM it’s apparently all just an atom. But I’ve never heard someone say it messed up in any way, that it was buggy or hard to use or failed to…

Clojure atoms use STM, though. I've been writing Clojure for almost a decade now, it's not that STM isn't great, it's just that immutable data will carry you a very long way - you just don't need coordinated mutation except in very narrow circumstances. In those circumstances STM is great! I have no complaints. But it just doesn't come up very often.

That’s incorrect. Only refs+dosync use stm. https://clojure.org/reference/refs

Not atoms.

From Hickey’s History of Clojure paper:

“ Taking on the design and implementation of an STM was a lot to add atop designing a programming language. In practice, the STM is rarely needed or used. It is quite common for Clojure programs to use only atoms for state, and even then only one or a handful of atoms in an entire program. But when a program needs coordinated state it really needs it, and without the STM I did not think Clojure would be fully practical.”

https://dl.acm.org/doi/pdf/10.1145/3386321

Atoms do an atomic compare and swap. It’s not the same thing.

Post reply on HN