Live data from Hacker News

Imperative Haskell

vaibhavsagar.com

71–73 of 73 posts

Re: Imperative Haskell

#71
post #67
post #8

Earlier quoted context omitted.

I tried to do some quick benchmarks: % make hs Results: [25872791,24253954,21258158] make hs 6.53s user 3.99s system 245% cpu 4.282 total % make py 24029582 25343914 20814678 make py 22.37s user 0.11s system 99% cpu 22.593 total You can see the code as tested here[0]. I am not an expert on either Haskell or Python performance, all I did was use -O for python3 and -O2 for GHC. This was on a 2.8 GHz Core i7 Macbook, FW…

$ time make hs Results: [24639155,24977202,20874958] make hs 8.39s user 5.93s system 322% cpu 4.435 total $ time make py 24894022 25787638 21979201 make py 14.33s user 0.02s system 99% cpu 14.353 total $ time make py PYTHON=pypy3 25059732 25318854 21254890 make py PYTHON=pypy3 4.02s user 0.06s system 99% cpu 4.082 total

Very nice.

Re: Imperative Haskell

#72
post #3

As far as I'm concerned, purity is more fundamental than impurity, because we can always emulate impurity using a pure language (as is shown in this article), but it's not possible to emulate purity using an impure language. This only leaves us with the challenge of performance. While we can always describe e.g. x86 assembly in terms of a pure intermediate representation language (e.g. GHC Core), transforming this de…

Hmm...you mention x86 assembly. For some reason, we seem to be able to implement ("emulate") all these different languages in x86 assembly.

Re: Imperative Haskell

#73
post #50

Earlier quoted context omitted.

Performance matters a little bit - most of the time we don't make perfomance improvements. Really in a context where performance was of serious importance I would want to have an explicit model of it to be sure I could reason about it compositionally. I find any single effect is easy to reason about in isolation, it's the interaction that gets tricky. Viewing purity as isolating performance is just one perspective on…

Yes, compositional reasoning is important, but it depends on being able to substitute equivalent code. If you're too strict about what counts as equivalent (including performance in the type system, say) it would be harder to make local changes since fewer substitutions would be possible. You can look at const correctness in C++, Java checked exceptions, async versus non-async functions [1], and Rust's ownership mode…

> If you're too strict about what counts as equivalent (including performance in the type system, say) it would be harder to make local changes since fewer substitutions would be possible.

I think this is avoidable if your types/effects can decompose properly into orthogonal factors. E.g. with a Future type and a generic monad abstraction it's fairly easy to substitute a sync call for an async call - you have to be explicit about the change you're making, but only very slightly, and you'd never get confused between changing sync/async and changing the "actual" type that's returned.

Post reply on HN