News for hackers. Stuff that matters.
Re:Rust as a gateway drug to Haskell by slaymaker1907 on Wednesday June 14, 2017 @02:03AM (#14550905)
Something that I found about going from Haskell to Rust was that Rust provides many powerful abstractions without compromising on performance. It was very frustrating to try reasoning about performance in Haskell due to its laziness. Every language has quirks about how to write performant code, but Haskell is notorious in my mind for being quite easy to write obscenely slow code in.
Re:Rust as a gateway drug to Haskell by delhanty on Wednesday June 14, 2017 @02:30AM (#14550983)
>Every language has quirks about how to write performant code, but Haskell is notorious in my mind for being quite easy to write obscenely slow code in.

+1

One approach that occurred to me was to use Haskell and Hackage for prototyping a design and then a Rust implementation for production.

It also reminds me of this from several years ago: GHC honcho Simon-Peyton Jones saying the next Haskell will be strict, but still pure with effects only via monads. [1], [2].

Following on and presumably related to that PureScript is strict. [3]

[1] https://news.ycombinator.com/item?id=1924094

[2] http://www.cs.nott.ac.uk/%7Egmh/appsem-slides/peytonjones.pp... (PowerPoint) Slide 40

[3] https://github.com/purescript/purescript/wiki/Differences-fr...

Re:Rust as a gateway drug to Haskell by arianvanp on Wednesday June 14, 2017 @08:38AM (#14552255)
SPJ also noted that the original success of haskell was due to their pursuit of laziness. Because laziness has no place in a system with side effects, their pursuit of laziness and functional programming is what led them to discover the usefulness of monads for describing it in the first place. If they were pursuing a strict language instead, then they were allowed to take shortcuts, because sneaking in side effects is a lot easier. YEs maybe the next haskell will be strict, but getting to the point to make that decision required laziness.

SPJ made a great lecture about this. It is very easy to follow and a fun insight into the academic history of modern functional languages https://www.youtube.com/watch?v=re96UgMk6GQ

Re:Rust as a gateway drug to Haskell by mrkgnao on Wednesday June 14, 2017 @03:07AM (#14551135)
I'm under the impression that SPJ made that comment thinking of adoption (for a future "regrettably popular" Haskell), since the difficulty of reasoning about laziness does put people off. I might be wrong though: maybe he was arguing that laziness doesn't warrant the user and compiler-author cost it brings. I don't remember where I picked this up from.

Idris is strict too, but optional laziness is built into the compiler with the use of a special-cased Lazy wrapper of the form

  data Lazy a = Delay a
This is kind of the opposite of strictness annotations (bang-patterns) from Haskell, except one doesn't need to pattern-match on Delay or use it to wrap arguments to functions expecting Lazy values. The Idris compiler can do something like "laziness analysis" (admittedly trivial in comparison to GHC's strictness analyser) to introduce and eliminate Delay constructors automatically. The laziness information is carried around in the types:

  force : Lazy a -> a
  force a = a
https://github.com/idris-lang/Idris-dev/wiki/Unofficial-FAQ#...

(purescript-lazy is also a thing, but I think it's not as seamless because of the "no compiler magic" position.)

In any case, what about -XStrict? I've never used it (or -XStrictData either), but isn't it a solution to the laziness problem, albeit a nuke-ish one at that?

And while we're thinking ahead, let's talk about the project to get linear types (something similar to Rust lifetimes, but weaker) into GHC :)

https://ghc.haskell.org/trac/ghc/wiki/LinearTypes

Re:Rust as a gateway drug to Haskell by logicchains on Wednesday June 14, 2017 @09:49AM (#14552661)
>something similar to Rust lifetimes, but weaker

Why weaker? My understanding is that linear types provide a stronger guarantee than Rust's affine types: linear types guarantee that a value is used once, while affine types only guarantee that a value is used no more than once.

Re:Rust as a gateway drug to Haskell by Jweb_Guru on Wednesday June 14, 2017 @10:06AM (#14552783)
Lifetimes are not the same as linear (or affine) types... they're related to "fractional permissions" in the upcoming formalism (and also related to region types found in many other systems, which can be partially emulated with monads).
Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @11:36AM (#14553485)
>GHC honcho Simon-Peyton Jones saying the next Haskell will be strict,

I think all he meant that strictness was an interesting paradigm that would differentiate a language enough to justify its existence alongside Haskell.

>Following on and presumably related to that PureScript is strict

Partly also to distinguish from GHCJS. Laziness in a strict language is really hard and PureScript generates semi-readable JavaScript.

Re:Rust as a gateway drug to Haskell by wyager on Wednesday June 14, 2017 @02:54AM (#14551083)
This is a very overstated concern, in my opinion. Based on my experience, once you learn the common gotchas (lazy folds, WHNF, etc.) it's rarely an issue. Real-world programs (web servers, databases, etc.) typically end up using frameworks that deal with strictness concerns for you anyway. For maybe the first couple weeks I was learning Haskell, this was a source of confusion, but I don't seem to run into it anymore.

If it's really a struggle for some reason, you can always take the nuclear option and enable strict mode on your code.

Haskell is very good for writing extremely fast code that's also extremely composable, which most languages (even Rust, to a substantial degree) really struggle with. Haskell's pure non-strict semantics and support for fusion/rewrite systems means that you can write complex operations on vectors, byte arrays, text, etc. that span multiple modules but get compiled down to extremely tight in-place assembly code. Another way of looking at it is that the economies of scale for Haskell are very different. There's a higher up-front cost because you have to learn about how strictness works, but as a consequence you can write vastly more complicated programs that are, say, 80% as fast as hand-optimized C for only 10% of the effort of hand-optimized C.

Re:Rust as a gateway drug to Haskell by delhanty on Wednesday June 14, 2017 @03:22AM (#14551188)
> .. you can write vastly more complicated programs that are, say, 80% as fast as hand-optimized C for only 10% of the effort of hand-optimized C.

Computer Language Benchmarks of GHC versus C don't seem to be close to matching your 80% as fast claim [1]. Also, the 10% of the effort of hand-optimized C bit - seem to recall there was a caveat - "if you happen to Don Stewart" [2].

The following is just my vague, uninformed impression, but Haskell and Go seem to be opposite ends of a spectrum, with Rust somewhere in between:

Haskell: good for expert individuals and small teams. The language is highly sophisticated and the compiler is rather slow. At heart, it's a research language, so the direction might not always suit production use. If you contract out to a Haskell development shop, who do you turn to with your Haskell code-base if things don't work out?

Go: designed by Google for their use-case - large teams of commodity programmers. It's very quick to onboard programmers - they can be productive and non-dangerous quickly. The language is very simple and the compiler is very quick - which is again good for scaling large teams.

[1] https://benchmarksgame.alioth.debian.org/u64q/compare.php?la...

[2] https://donsbot.wordpress.com/2008/05/06/write-haskell-as-fa...

Re:Rust as a gateway drug to Haskell by wyager on Wednesday June 14, 2017 @03:39AM (#14551230)
The benchmarks game falls squarely under the umbrella of "short, simple programs", not the sort of real-world stuff where you would benefit from having a language that scales well. That said, Haskell performs pretty well in the toy benchmarks anyway.

Your comparison between Haskell and Go is about market size, not language design. I suspect you would have a similarly hard time finding Rust devs as Haskell devs (i.e. mildly less convenient than a popular language like Python or Go).

Re:Rust as a gateway drug to Haskell by delhanty on Wednesday June 14, 2017 @04:21AM (#14551360)
> .. you can write vastly more complicated programs that are, say, 80% as fast as hand-optimized C for only 10% of the effort of hand-optimized C.

I don't mean to be personal, but your quantative claim smells a little like unsubstantiated BS. Do you have any data to back it up?

> That said, Haskell performs pretty well in the toy benchmarks anyway.

Currently, "pretty well" looks like GHC performance is 50% to 10% of hand-crafted C using perhaps 5 times as much memory. (If the GHC program builds at all that is.)

fannkuch-redux

Haskell GHC: 16.70 sec 7,628 mem

C gcc: 8.97 sec 1,660 mem

spectral-norm

Haskell GHC: 4.06 sec, 9,880 mem

C gcc: 1.99 sec, 1,824 mem

n-body

Haskell GHC: 24.48 sec, 6,468 mem

C gcc: 9.96 sec, 1,016 mem

reverse-complement

Haskell GHC: 1.39 sec, 132,176 mem

C gcc: 0.42 sec, 143,948 mem

mandelbrot

Haskell GHC: 11.64 sec, 41,180 mem

C gcc: 1.65 sec, 32,684 mem

fasta

Haskell GHC: 14.68 sec, 455,088 mem

C gcc: 1.33 sec, 2,856 mem

binary-trees

Haskell GHC: 26.28 sec 511,444 mem

C gcc: 2.38 sec 131,728 mem

k-nucleotide

Haskell GHC: Make Error

C gcc 0.06 sec ? mem

pidigits

Haskell GHC: Make Error

C gcc: 0.06 sec ? mem

regex-redux

Haskell GHC: Make Error

C gcc: 0.02 sec ? mem

Haskell GHC: The Glorious Glasgow Haskell Compilation System, version 8.0.2

C gcc: gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406

Re:Rust as a gateway drug to Haskell by Tarean on Wednesday June 14, 2017 @05:19AM (#14551525)
The make errors are a bit weird because the programs build on my machine no problem.

In parts haskells slowness seems to be because no one cares enough to work on it. Can't say for sure, though, so maybe I just should try a task and implement it to see how fast it'd be without amazing optimization foo.

Although of course these benchmarks aren't really representative of the real world because they'd just end up as a c ffi call in most languages if they actually were that performance critical.

Re:Rust as a gateway drug to Haskell by delhanty on Wednesday June 14, 2017 @08:28AM (#14552204)
I agree with all that, particularly the bit about the c ffi call. It's more relevant to compare Rust with C and C++, as Rust is a language that could reasonably display C for the ffi call.

But then remember that @wyager is claiming

>80% as fast as hand-optimized C for only 10% of the effort of hand-optimized C

If it's really only 10% of the effort then one shouldn't really have "to work on it" to get semi-decent performance.

A more modest claim of say:

50% as fast as hand-optimized C for only 20% of the effort of hand-optimized C

would have been more credible and still a big win for many use cases.

Re:Rust as a gateway drug to Haskell by Tarean on Thursday June 15, 2017 @04:39PM (#14564159)
Tried my hand at the knucleotide[1] one. Lifted the algorithm from the fastest rust solution. As optimization I dropped some Unpack pragmas and strictness annotations, used Data.Hashtable.Cuckoo for in-place updating hash tables because that seemed necessary for the task, and added naive parallelization via

   let outputs = map (exec content) tasks `using` parList rseq
That got around 24 seconds which seems acceptable for a fairly straightforward solution that is around half the size of the rust one I copied. Might try to optimize later.

[1]: http://benchmarksgame.alioth.debian.org/u64q/knucleotide.htm...

Re:Rust as a gateway drug to Haskell by igouy on Friday June 16, 2017 @05:05PM (#14572642)
Re:Rust as a gateway drug to Haskell by igouy on Wednesday June 14, 2017 @01:14PM (#14554195)
That pi-digits program does not "build on [your] machine no problem".

It cannot.

The line "main = putStr.pidgits.read.head =<< getArgs" has been commented out because the program author has optimised-away some of the work that must be done.

Re:Rust as a gateway drug to Haskell by Tarean on Wednesday June 14, 2017 @04:23PM (#14555821)
Fair enough, I only checked the two knucleotide programs which both failed because of missing dependencies.
Re:Rust as a gateway drug to Haskell by igouy on Friday June 16, 2017 @05:04PM (#14572639)
>> The make errors are a bit weird because the programs build on my machine no problem. <<

My fault (except for pi-digits and regex-redux).

I neglected to work-through the force-reinstalls that inevitably follow my update of the GHC compiler.

Done.

Re:Rust as a gateway drug to Haskell by delhanty on Wednesday June 14, 2017 @04:29AM (#14551389)
Language design choice pretty obviously relates to market size as my comment makes clear.

I referenced Rust because that was the article was about.

Swift and F# are languages that are not as basic as Go, but easier to find devs than Haskell.

That said, Rust has a lot going for it, even if there are a lot less devs than Swift.

Re:Rust as a gateway drug to Haskell by BigJono on Wednesday June 14, 2017 @08:22AM (#14552178)
"mildly" less convenient? Maybe in SV. I'll bet if I tried to hire a semi-experienced Rust developer here in Melbourne I'd be looking until Christmas at least haha.
Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @05:06PM (#14556119)
>Computer Language Benchmarks of GHC versus C don't seem to be close to matching your 80% as fast claim [1]. Also, the 10% of the effort of hand-optimized C bit - seem to recall there was a caveat - "if you happen to Don Stewart" [2].

That's a really bad benchmark. The power of Haskell is not that it's fast for generating the Mandelbrot set, it's that it allows you to things you couldn't do in any other language while still being fast enough to write e.g. compilers (Idris) or web services (Yesod).

Re:Rust as a gateway drug to Haskell by igouy on Thursday June 15, 2017 @11:54AM (#14561540)
Really bad benchmark? Inappropriate choice of benchmark?
Re:Rust as a gateway drug to Haskell by vmchale on Thursday June 15, 2017 @06:01PM (#14564799)
I have a hard time seeing the value in a Mandelbrot benchmark. I absolutely don't have a problem with benchmarks that make Haskell look bad (e.g. directory traversal, regex), but I would like a benchmark that provides insight into the code you'd feasibly be writing in that language.
Re:Rust as a gateway drug to Haskell by igouy on Friday June 16, 2017 @12:28PM (#14570308)
Isn't Haskell intended to be a general purpose programming language?
Re:Rust as a gateway drug to Haskell by linkmotif on Wednesday June 14, 2017 @02:08PM (#14554686)
> commodity programmers

Heh

Re:Rust as a gateway drug to Haskell by marcosdumay on Wednesday June 14, 2017 @08:06AM (#14552102)
Some real world programs have a very clear request-response cycle that Haskell deals with very well (although a more predictable garbage collector would be great).

Other real world programs have a strict "always push things into the world, react to inputs" cycle that Haskell has trouble supporting.

Re:Rust as a gateway drug to Haskell by JoshTriplett on Wednesday June 14, 2017 @02:40AM (#14551020)
I had the same experience: I really enjoyed the expressiveness and power of Haskell, as well as the strong type system. But Rust gives me all those things, as well as iterators for laziness when desired, without the pervasive laziness that had me constantly chasing down space leaks and adding strictness annotations.
Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @11:42AM (#14553534)
>But Rust gives me all those things, as well as iterators for laziness when desired, without the pervasive laziness that had me constantly chasing down space leaks

Well, yeah, Rust has manual memory management. Of course you don't get space leaks.

Anyways, Rust's laziness is not on par with Haskell. Iterators are great but it's not at all the same as e.g. GHC's lazy IO.

Re:Rust as a gateway drug to Haskell by JoshTriplett on Wednesday June 14, 2017 @12:43PM (#14553933)
> Well, yeah, Rust has manual memory management. Of course you don't get space leaks.

I wouldn't call Rust's memory management "manual". It's the only language I know of that I'd describe as having automatic memory management without garbage collection.

> Anyways, Rust's laziness is not on par with Haskell. Iterators are great but it's not at all the same as e.g. GHC's lazy IO.

Iterators, futures, and macros (for creating new language constructs) tend to provide the laziness I want. Beyond that, I've tended to find laziness as much a source of bugs as features. (Speaking from a perspective of having written and maintained large programs in Haskell, and in Rust.)

Re:Rust as a gateway drug to Haskell by oconnore on Wednesday June 14, 2017 @02:38AM (#14551015)
Comparing it against Rust doesn't really seem fair. If I wasn't using Haskell, I'd be writing Erlang, and last I checked GHC is much faster than Erlang/OTP. Certainly faster than CPython, Ruby, and most Node.js.

Trying to compete with Rust or C++ performance in Haskell is certainly frustrating to reason about :)

Re:Rust as a gateway drug to Haskell by lambdadmitry on Wednesday June 14, 2017 @07:41AM (#14552006)
I would argue that at least for client-server apps Erlang is faster. Here is why: in most cases the perceived performance of a server is constrained by maximum (or 99%, whatever) latency, not by throughput. Moreover, you can scale throughput horizontally, while scaling for latency is more or less impossible. Haskell's GC can give you horrendous pauses (see [1][2]), ruining perceived performance. Erlang, on the other hand, is thoroughly optimized for minimal latency.

TL;DR: "fast" isn't well-defined, and for a lot (or even most) applications "fast" is about latency, not throughput, and Erlang is "faster" in that sense.

[1] https://making.pusher.com/latency-working-set-ghc-gc-pick-tw...

[2] they eventually abandoned Haskell for Go https://making.pusher.com/golangs-real-time-gc-in-theory-and...

Re:Rust as a gateway drug to Haskell by Tarean on Wednesday June 14, 2017 @04:19PM (#14555781)
Yeah, the worst case of ghc's garbage collection is awful and can dwarf the actual work being done. That's the man driving factor behind adding linear types to haskell - they let long lived and large data live on a separate non-gced heap.

The other big part of this is that it can make stream fusion predictable. Currently haskell programs can become 100x slower or faster after some innocuous change, so linear types will make it a lot easier to write fast haskell in general.

http://blog.tweag.io/posts/2017-03-13-linear-types.html

Re:Rust as a gateway drug to Haskell by pletnes on Wednesday June 14, 2017 @02:52AM (#14551070)
While "GHC is faster than CPython" is a fairly accurate generalization, I still think python performance is easier to reason about. Haskell can give you fast code, but sometimes it will be super slow for no obvious reason.
Re:Rust as a gateway drug to Haskell by chongli on Wednesday June 14, 2017 @07:30AM (#14551970)
super slow for no obvious reason

Obviousness is hard to pin down. What may be completely obscure to a Haskell beginner is obvious to a veteran. Is it really fair to count people's strict-language preconceptions against Haskell? I don't know.

GHC provides a wealth of profiling tools that an expert Haskell user can employ to find space leaks. Heck, experts generally know where to look (excessive use of lists, spine-nonstrict data structures) so that the profiling tools become a last resort.

Re:Rust as a gateway drug to Haskell by whatshisface on Wednesday June 14, 2017 @08:27AM (#14552198)
A sufficiently smart [compiler | developer] can [make it so that | think] anything is easy.

Since performance is exactly a measure of the number of imperative steps that need to happen in a program, low level imperative langauages are going to win in performance-obviousness every time. (Rust probably beating C in terms of avoiding memory problems, C probably beating rust in terms of not supporting language constructs that can make a single line worse than O(1).)

"Accidentally" asking the language to do something time-expensive is as impossible in C as forgetting a free() in Haskell.

Re:Rust as a gateway drug to Haskell by cesarb on Wednesday June 14, 2017 @09:47AM (#14552641)
> "Accidentally" asking the language to do something time-expensive is as impossible in C as forgetting a free() in Haskell.

Unless you use GCC's cleanup extension (which runs an arbitrary function when leaving a scope, similar to Rust's Drop trait). Or evil macros which turn innocent-looking code into something else (a well-known project, in some compilation modes, redefines the "if" keyword to track how many times each branch is taken). Or both at the same time (like hiding GCC's cleanup extension with a macro).

Re:Rust as a gateway drug to Haskell by xwvvvvwx on Wednesday June 14, 2017 @09:48AM (#14552645)
Since performance is exactly a measure of the number of imperative steps that need to happen in a program

This is an oversimplification. Writing fast code for modern processors is all about how much time you spend waiting for memory.

Re:Rust as a gateway drug to Haskell by FullyFunctional on Thursday June 15, 2017 @01:39PM (#14562518)
This is an oversimplification. Some compute intensive parts can get significant speed ups through careful use of data parallelism (such as SIMD). Others needs parallelism at the thread level. Etc. Optimizing for memory patterns is important as is trying to keep the working set within a near-level cache.
Re:Rust as a gateway drug to Haskell by saosebastiao on Wednesday June 14, 2017 @11:25AM (#14553406)
Cache locality will never beat algorithmic complexity as a performance factor. Don't exaggerate its importance.
Re:Rust as a gateway drug to Haskell by falcolas on Wednesday June 14, 2017 @12:18PM (#14553765)
It can, when the constant portion of the algorithm chosen is high and the number of items being pushed through the algorithm is low.

e.g. bubblesort will beat quicksort for tiny lists or large lists which are already sorted.

Or, put another way, 1000 operations against 1ns latency memory (L1) has the same performance as 10 operations against 100ns latency memory (RAM).

Re:Rust as a gateway drug to Haskell by motet_a on Wednesday June 14, 2017 @03:29AM (#14551202)
Moreover, CPython is a interpreter without JIT while GHC compiles to machine code. This is totally different. IMHO, it is much more correct to compare a JIT-enabled interpreter to GHC.
Re:Rust as a gateway drug to Haskell by hajile on Wednesday June 14, 2017 @09:34AM (#14552555)
Why not SML/CML where you basically get haskell syntax and types, but get modules, no laziness, and you can mutate things when it's more efficient to do so.
Re:Rust as a gateway drug to Haskell by lmm on Wednesday June 14, 2017 @12:03PM (#14553658)
I couldn't stand to work without HKT now that I'm used to them. (Hell, I'm struggling with Scala's lack of polykinded types; you don't need them until you do, but then you really need them).
Re:Rust as a gateway drug to Haskell by adamwk on Wednesday June 14, 2017 @12:49PM (#14553974)
MLs have higher kinder types.
Re:Rust as a gateway drug to Haskell by lmm on Thursday June 15, 2017 @04:02AM (#14558655)
Which ones? OCaml is planning to add them via its "modular implicits" work but that hasn't happened yet; none of the SML implementations I used mentioned them.
Re:Rust as a gateway drug to Haskell by adamwk on Thursday June 15, 2017 @05:47PM (#14564675)
I think you're confusing higher-kinded types with type classes. You're right that neither has type classes.
Re:Rust as a gateway drug to Haskell by FullyFunctional on Thursday June 15, 2017 @01:44PM (#14562565)
The difference in both syntax and type system is vast, unless you are coming from, say Fortran or APL.
Re:Rust as a gateway drug to Haskell by dpratt on Wednesday June 14, 2017 @09:48AM (#14552649)
Scala would like to have a word with you.
Re:Rust as a gateway drug to Haskell by Symmetry on Wednesday June 14, 2017 @01:13PM (#14554178)
Something I've always wondered about Haskell is whether there is, in practice, rope for the compiler to optimize things away from the theoretical underlying implementation. For instance a C compiler is free to turn

  for (int i = 0; i < N; i++) {
    a[i] = 2*b[i];
  }
  for (int i = 0; i < N; i++) {
    c[i] = 2*d[i];
  }
into

  for (int i = 0; i < N; i+=2) {
    a[i] = 2*b[i];
    a[i+1] = 2*b[i+1];
    c[i] = 2*d[i];
    c[i+1] = 2*d[i+1];
  }
It seems like GHC ought to similarly be able to turn some

  foo :: [Int] -> [Int]
into

  foo :: [(Int, Int)] -> [(Int, Int)]
under the covers for a similar speedup as long as it can, as with the C compiler, handle the case of an odd length with a bit of extra code.

There are limits to how much you can restructure a list that's exported outside the compilation unit (my Haskell knowledge is fuzzy here so that's probably not the right terminology). And if the list is being re-stitched in odd ways it might be a bad idea. But as far as I can tell it ought to be doable and useful in most common cases. Of course maybe it's already doing this in those cases where it can prove that it works and that's why Haskell performance generally is good but fragile.

Re:Rust as a gateway drug to Haskell by haldean on Wednesday June 14, 2017 @01:18PM (#14554234)
Haskell performs a very cool optimization called "stream fusion" to deal with a whole class of traversal optimization problems; stream fusion removes intermediate list results completely, and bundles a bunch of things that look like maps/reduces/filters into a single operation. Your example doesn't quite hit it, but a similar bit of code like:

    for (int i = 0; i < N; i++)
        a[i] = 2 * b[i];
    for (int i = 0; i < N; i++)
        c[i] = 2 * a[i] + b[i];
    t = 0;
    for (int i = 0; i < N; i++)
        if (b[i] % 2 == 0) t += c[i];
Would be rewritten to the equivalent of:

    t = 0;
    for (int i = 0; i < N; i++)
        if (b[i] % 2 == 0) t += 5 * b[i];
Lots more info on the GHC optimizations page: https://wiki.haskell.org/GHC_optimisations#Fusion
Re:Rust as a gateway drug to Haskell by Symmetry on Wednesday June 14, 2017 @01:30PM (#14554363)
Yes, stream fusion is super nifty. But can Haskell alter the size of the chunks it's sending through the stream? There was a recent HN thread about how GNU 'yes' is so fast thanks to buffering. Obviously too large a buffer would blow out the cache and stream fusion avoids that but a moderate amount of buffering so that you're neither working array by array nor element by element but cachable chunk by cachable chunk should be a happy middle. And with Haskell lists reduce pointer chasing as well.
Re:Rust as a gateway drug to Haskell by haldean on Wednesday June 14, 2017 @01:59PM (#14554620)
I think that the issue you're describing about `yes` was around building a buffer and issuing one big write() syscall instead of a bunch of small ones. I'm not sure about the actual implementation of the IO monad, and whether or not it coalesces call to write(), but it would definitely be possible. Also, idiomatic Haskell would make large writes, because usually (at least in my experience) you create a large string/Text representing your output, and then putStrLn or print it all at once.

In regards to assembling the stream: when the list is actually materialized, I assume it's done one element at a time, but the LLVM backend that GHC uses might be doing some loop unrolling, but I'm not sure.

Stream fusion doesn't require that all of the streams be the same type, though! Elements at different points in the stream can have wildly different sizes. For example, this would be fused:

    sum . map length . map double $ ["hello", "Symmetry"]
        where double x = concat [x x]
That will never materialize a list of Strings, even though at two points in the stream you had a stream of strings.
Re:Rust as a gateway drug to Haskell by hydraz on Wednesday June 14, 2017 @04:51PM (#14556026)
GHC doesn't actually perform stream fusion. Not by default, anyway: The default (by that I mean "ships with base", not that it's baked into the compiler) is something weaker, called build/foldr fusion, described by this rule:

  foldr z f (build g) = g f z
Foldr is the usual catamorphism for the inductive list type, and build is an "abstracted constructor", of sorts:

  build :: (forall b. (a -> b -> b) -> b -> b) -> [a]
  build f = f (:) []
Note that build's argument is rank-2 polymorphic, and also the same as foldr's type.
Re:Rust as a gateway drug to Haskell by georgewsinger on Wednesday June 14, 2017 @07:10AM (#14551891)
Haskell's laziness is an issue for you? Then how do strictness annotations (and/or module flags) not solve this problem?

Haskell also has inline-C FFI support for "type safe" performance escape hatches (in the sense that you can manually bring C constructs into Haskell's type system): https://github.com/fpco/inline-c

The only way that Haskell inescapably suffers from performance hits (that I'm aware of) is not in its laziness or lack of imperative programming support, but in its periodic GC pauses. In such cases where GC pauses are an issue, I still think you can -- in principle -- write more and more performance critical pieces of your application in a non-GC language (in fact, you could do this in Rust just as well as C/C++). You can also manually trigger a GC pass, although you cannot -- to my knowledge -- manually stop and start GC passes in your code.

This is the approach I'm currently taking in a performance critical VR application where GC pauses could absolutely be an issue (using as much Haskell as possible, with C and GC triggers as an escape hatch). And if someone could point out a flaw in my reasoning (in particular, how GC pauses might be inevitably avoided even with C FFI), I would gladly pay them money, because it's so important I not get this one wrong :).

Re:Rust as a gateway drug to Haskell by mej10 on Wednesday June 14, 2017 @08:31AM (#14552216)
It is also possible to avoid GC pauses causing problems in your application with a load balancer. Basically shifting load between haskell processes when a big GC is imminent.

Read about that technique from Simon Marlow of Facebook's Haskell team. Of course it would be awesome to not have to worry about that.

Re:Rust as a gateway drug to Haskell by georgewsinger on Wednesday June 14, 2017 @09:02AM (#14552388)
Nice -- this technique never came up when I searched /r/haskell for GC pause workarounds. And yes -- it would be awesome not to have to worry about this.
Re:Rust as a gateway drug to Haskell by dllthomas on Wednesday June 14, 2017 @10:14AM (#14552859)
> Then how do strictness annotations (and/or module flags) not solve this problem?

Strictness annotations (and associated pragmas) only change the strictness of constructors and functions defined in my modules. I still have to reason about laziness as I use almost anything from the Haskell ecosystem.

Re:Rust as a gateway drug to Haskell by georgewsinger on Wednesday June 14, 2017 @10:35AM (#14553005)
Good point. I wonder if there are Strict versions of the Prelude that could help out?
Re:Rust as a gateway drug to Haskell by agumonkey on Wednesday June 14, 2017 @02:47AM (#14551046)
Hence a reason why so many people are sticking to ML despite the lack of social momentum.
Re:Rust as a gateway drug to Haskell by zem on Wednesday June 14, 2017 @03:06AM (#14551125)
ocaml is a great language in its own right too; the only haskell features I find myself really missing are do notation and operator overloading.
Re:Rust as a gateway drug to Haskell by hxegon on Wednesday June 14, 2017 @01:05PM (#14554120)
OCaml seems like the ideal language for me on the surface, but the onboarding process is... suboptimal IMO. There's a lack of good soft/hard documentation (AKA the "no, type signatures are not sufficient documentation" problem), but my biggest turn off is the multiple standard libraries. Some might see that as a plus, but when I'm just trying to get a small learning project off the ground, and I find out there's a critical library I need that's incompatible with the stdlib I'm using is a huge bummer.

Not saying these are insurmountable, unforgivable problems, just really annoying.

Re:Rust as a gateway drug to Haskell by wtetzner on Monday June 19, 2017 @10:39PM (#14591836)
I feel like the biggest thing missing from OCaml is a Cargo-like build tool (probably using OPAM under the hood for dependency management). It would also be nice if OPAM had better cross platform support. The only way I could get it working on Windows was through one of the distributions that bundled Cygwin.
Re:Rust as a gateway drug to Haskell by kornakiewicz on Wednesday June 14, 2017 @04:30AM (#14551393)
F# does have operator overloading.
Re:Rust as a gateway drug to Haskell by systems on Wednesday June 14, 2017 @10:32AM (#14552988)
but F# doesn't have Ocaml's performance, which I believe was the point being made for ML over Haskell

I honestly don't know how F# compares to Haskell over performance

Re:Rust as a gateway drug to Haskell by bpicolo on Wednesday June 14, 2017 @02:05PM (#14554668)
F# is essentially just C#, which should be reasonably performant? It's possible the persistent data structures aren't optimized I guess?

Pity something's busted in the benchmarks game: http://benchmarksgame.alioth.debian.org/u64q/fsharp.html

Re:Rust as a gateway drug to Haskell by igouy on Thursday June 15, 2017 @11:49AM (#14561495)
It wasn't busted with .NET Core 1.0.1 005db40cd1.

Is F# working with .NET Core 2.0 Preview 1 for you?

Re:Rust as a gateway drug to Haskell by bpicolo on Thursday June 15, 2017 @12:24PM (#14561820)
Haven't tried out .NET Core 2 yet, actually.
Re:Rust as a gateway drug to Haskell by igouy on Thursday June 15, 2017 @04:38PM (#14564143)
Re:Rust as a gateway drug to Haskell by wtetzner on Monday June 19, 2017 @10:41PM (#14591841)
But it's missing the module system, which is IMHO OCaml's best feature.
Re:Rust as a gateway drug to Haskell by kornish on Wednesday June 14, 2017 @05:44AM (#14551602)
Also the multicore concurrency.
Re:Rust as a gateway drug to Haskell by agumonkey on Wednesday June 14, 2017 @05:07AM (#14551487)
Some people also complain about a tiny set of syntactic issues. Other than that I like both ml and ocaml.
Re:Rust as a gateway drug to Haskell by pjmlp on Wednesday June 14, 2017 @05:36AM (#14551577)
Having learned ML languages via Caml Light, I never understood what those complaints are about.

Maybe the only thing I would complain would be the separation between integer and floating point math.

Re:Rust as a gateway drug to Haskell by agumonkey on Wednesday June 14, 2017 @06:45AM (#14551819)
not even the monomorphism, I forgot but there's a few warts at the syntactic level only.
Re:Rust as a gateway drug to Haskell by k__ on Wednesday June 14, 2017 @06:58AM (#14551853)
A few months ago I read monomorphism is the way to go performance wise.

Something about people writing fast code with Flow/TypeScript than with plain JavaScript because the typing leads to less polymorphic code which is easier to optimize for the compiler.

Re:Rust as a gateway drug to Haskell by tom_mellior on Wednesday June 14, 2017 @09:56AM (#14552699)
In this context, "monomorphism" just meant that OCaml requires you to write "+" to add integers and "+." to add floats (and yet other things to add bignums or whatever).

This has nothing to do with performance per se. It doesn't make OCaml code faster than languages that allow you to write "+" for both int+int and float+float. The compiler knows anyway.

Re:Rust as a gateway drug to Haskell by k__ on Wednesday June 14, 2017 @06:59AM (#14551859)
But that's what most devs do, right? If it doesn't look like C it's ugly, haha.

Anyway, Reason seems to have a bit nicer syntax than OCaml, I think.

Re:Rust as a gateway drug to Haskell by firethief on Wednesday June 14, 2017 @02:48PM (#14555000)
Reason seeks to destandardize syntax, a fascinating experiment I'd prefer to watch in a language not already held back by community fragmentation.
Re:Rust as a gateway drug to Haskell by aaron-lebo on Wednesday June 14, 2017 @02:07AM (#14550917)
This is what's really nice about Nim. It writes like Python, but is fast like Rust.

Ran across Option in it the other day, though it's not used heavily. I really wish there was something like Haskell but with a runtime like Nim or Go. Perhaps that is OCaml?

Re:Rust as a gateway drug to Haskell by captainmuon on Wednesday June 14, 2017 @02:48AM (#14551051)
Exactly. For me, Haskell was a gateway to Nim. I wanted something that feels familiar, but with a strong type system and native speed.

I wish I could invest some time in working with Nim. It doesn't get as much attention as it deserves in my opinion, and it would really benefit from growing the community a bit.

Re:Rust as a gateway drug to Haskell by nicoburns on Wednesday June 14, 2017 @04:45AM (#14551430)
Have you looked at Swift? It's pretty similar to Rust, but eschews all the lifetime stuff in favour of a runtime that does reference counting.
Re:Rust as a gateway drug to Haskell by beefsack on Wednesday June 14, 2017 @07:12AM (#14551899)
Swift is useful if you're an Apple developer only targeting Apple users, seems like a bit of a niche.
Re:Rust as a gateway drug to Haskell by AlexeyBrin on Wednesday June 14, 2017 @07:53AM (#14552047)
Swift works reasonably well on Linux. You can even run Swift on Windows 10 through Windows Subsystem for Linux.
Re:Rust as a gateway drug to Haskell by beefsack on Wednesday June 14, 2017 @08:17AM (#14552158)
I tried under Arch a few months ago and found swathes of the standard library didn't appear to work, is this something which has been fixed?
Re:Rust as a gateway drug to Haskell by AlexeyBrin on Wednesday June 14, 2017 @09:32AM (#14552541)
AFAIK only the core language is fully ported, for the libraries ... it is a work in progress.
Re:Rust as a gateway drug to Haskell by jandrese on Wednesday June 14, 2017 @11:12AM (#14553315)
In other words it is useless currently.
Re:Rust as a gateway drug to Haskell by AlexeyBrin on Wednesday June 14, 2017 @03:33PM (#14555388)
Tell that to IBM that uses Swift in production. See IBM's Kitura open source server framework if you are interested.
Re:Rust as a gateway drug to Haskell by jandrese on Thursday June 15, 2017 @09:55PM (#14566074)
They use a language without a standard library in production?
Re:Rust as a gateway drug to Haskell by AlexeyBrin on Friday June 16, 2017 @07:50AM (#14568121)
I'm sure you can find yourself the answer if you are really interested, here is an example: http://www.computerworld.com/article/3122994/apple-mac/ibm-s...

Or this one https://developer.ibm.com/swift/

Re:Rust as a gateway drug to Haskell by pjmlp on Wednesday June 14, 2017 @05:38AM (#14551588)
Actually Swift 4.0 just got some memory ownership support, with more to come later.
Re:Rust as a gateway drug to Haskell by kibwen on Wednesday June 14, 2017 @12:51PM (#14553987)
Link? Last I checked all of Swift's ownership ideas were just in-progress proposals, with implementation to be left to far-future releases.
Re:Rust as a gateway drug to Haskell by pjmlp on Wednesday June 14, 2017 @01:13PM (#14554184)
Watch the video about the talk, what is new in Swift 4.0 at WWDC 2017.

Basically 4.0 will introduce the notion of exclusive access, with more affine type ideas to follow up on 4.x.

EDIT: This feature is described by SE-0176.

https://github.com/apple/swift-evolution/blob/master/proposa...

Re:Rust as a gateway drug to Haskell by yitzg on Thursday June 15, 2017 @03:31AM (#14558542)
As a Haskell practitioner in industry - for several years we have been creating technical documentation sites for large enterprise customers, providing fast semantic search for gigabytes of content serving millions of users - I can attest that this simply isn't true. We have found that reasoning about performance in a pure functional language is not harder than for any other kind of mainstream language. Except in the sense that it is different, so not all of your skills and intuition from other languages necessarily apply.
Re:Rust as a gateway drug to Haskell by k__ on Wednesday June 14, 2017 @07:00AM (#14551866)
Wasn't the selling point of laziness performance?

"It only does what is needed!"

I didn't use Haskell but Nix and at least there it seemed reasonable to "not do" everything.

Re:Rust as a gateway drug to Haskell by Tuna-Fish on Wednesday June 14, 2017 @09:04AM (#14552393)
Haskell can be made very fast. The problem is that at least for me, performance is often quite non-intuitive. As in, make tiny change to program, it is now a hundred times slower. Then you get to hunt down the reason why it's now doing too much work/ why stream fusion isn't working anymore/why it's leaking so much space/etc for hours.

I enjoy writing Haskell for small hobby projects, but I doubt I would choose it for real work now that F# and Rust exist.

Re:Rust as a gateway drug to Haskell by snovv_crash on Wednesday June 14, 2017 @08:18AM (#14552162)
In other languages when the compiler misses an optimization you get a constant order penalty on a small piece of code.

In Haskell when the compiler misses an optimization the performance hit is potentially unbounded, as it could think anything is a dependency. (You want the first N digits of pi? Just wait while I calculate all of them for you...)

Re:Rust as a gateway drug to Haskell by codygman on Thursday June 15, 2017 @02:55AM (#14558434)
> You want the first N digits of pi? Just wait while I calculate all of them for you...

I don't think that example cold actually happen, or at least I can't see how it would happen in Haskell.

Re:Rust as a gateway drug to Haskell by tome on Wednesday June 14, 2017 @09:37AM (#14552576)
I don't think anything is the unique selling point of laziness. Wikipedia[1] says "The benefits of lazy evaluation include:

* The ability to define control flow (structures) as abstractions instead of primitives.

* The ability to define potentially infinite data structures. This allows for more straightforward implementation of some algorithms.

* Performance increases by avoiding needless calculations, and error conditions in evaluating compound expressions."

In my several-year experience as a professional Haskell developer the first and second points are at least an order of magnitude more important than the third.

[1] https://en.wikipedia.org/wiki/Lazy_evaluation

Re:Rust as a gateway drug to Haskell by Symmetry on Wednesday June 14, 2017 @12:56PM (#14554031)
Also in some cases laziness creates loop fusion between chained functions for much better cache locality.
Re:Rust as a gateway drug to Haskell by k__ on Wednesday June 14, 2017 @10:02AM (#14552752)
"the first and second points are at least an order of magnitude more important than the third."

No offense, but 'performance is not as important as...' is what basically all pro-FP devs say for years, still it seems that the rest of the world thinks exactly the opposite.

Re:Rust as a gateway drug to Haskell by tome on Wednesday June 14, 2017 @10:49AM (#14553129)
You've completely missed the point.

I make no claim about the importance of performance.

My claim is that the performance gains brought by lazy evaluation are far less important than the other gains it brings (because the performance gains it brings are rather small).

Re:Rust as a gateway drug to Haskell by k__ on Wednesday June 14, 2017 @11:51AM (#14553589)
Yes, you're right. I'm sorry.
Re:Rust as a gateway drug to Haskell by tome on Thursday June 15, 2017 @05:31AM (#14558936)
That's OK!
Re:Rust as a gateway drug to Haskell by tikhonj on Wednesday June 14, 2017 @10:50AM (#14553132)
It's hard to believe that a world where Ruby, Python and Node are massively popular cares about performance above expressiveness. Even Java became popular first and fast afterwards—not even talking about memory efficiency!

I'd agree that a lot of developers still over-index on performance though, probably because it's sexy and easy to measure.

Re:Rust as a gateway drug to Haskell by falcolas on Wednesday June 14, 2017 @12:22PM (#14553793)
> I'd agree that a lot of developers still over-index on performance though, probably because it's sexy and easy to measure.

To keep producing responsive compute programs as the complexity of those programs continues to rise while the single-core CPU performance remains steady, program performance must become more and more important.

Re:Rust as a gateway drug to Haskell by dllthomas on Wednesday June 14, 2017 @10:22AM (#14552900)
On the contrary, the rest of the world seems to think "the performance gains given by laziness" aren't worthwhile at all.

It's true that there are also performance costs associated with laziness, but those weren't under discussion.

Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @11:30AM (#14553438)
>It was very frustrating to try reasoning about performance in Haskell due to its laziness.

Conversely, I find it hard to achieve the same performance with strict code. I think it's likely a matter of familiarity.

>Haskell is notorious in my mind for being quite easy to write obscenely slow code in.

The standard prelude is flawed in many ways. Haskell 2020 will hopefully fix this. In the meantime: the recursion-schemes library might be of great use.

Re:Rust as a gateway drug to Haskell by thesz on Thursday June 15, 2017 @06:38AM (#14559193)
Something I found about going to Haskell from <any other language> is that Haskell provides many powerful abstractions without compromising on performance. Especially programmer's performance.

If you do not need to write notoriously slow code in Haskell, just don't do it. Use libraries (containers and mtl especially great), keep state strict (a handful of bang patterns).

I use Haskell's laziness with great success (look for paper "generating power of lazy semantics" it's fascinating; look "the essence of functional programming" for even more fascination). I use Haskell's flexibility with great success (how about beating C speed ten times? how about parallelization to all cores with couple lines of code?). It is really great language.

BTW, Haskell's RTS reuse chunk type field which is needed for implementation of laziness for synchronization and it is great! This means that it can provide everything that Java and/or .Net provides and get away with twice as less overhead for it.

Re:Rust as a gateway drug to Haskell by hellofunk on Wednesday June 14, 2017 @05:29AM (#14551551)
I don't use Haskell but didn't I read recently that the latest version of Haskell addresses this common concern by allowing you to turn off laziness altogether so everything evaluates eagerly?
Re:Rust as a gateway drug to Haskell by lkurusa on Wednesday June 14, 2017 @05:39AM (#14551593)
There is -XStrict, see here for a discussion: https://ghc.haskell.org/trac/ghc/wiki/StrictPragma
Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @11:50AM (#14553577)
>Haskell addresses this common concern by allowing you to turn off laziness altogether so everything evaluates eagerly

It's a common concern but it's a terrible critique. Laziness has many subtle benefits, but everyone whines about it because its pitfalls are decidedly not subtle.

Re:Rust as a gateway drug to Haskell by willtim on Wednesday June 14, 2017 @11:14AM (#14553329)
Most problems arise from using linked-lists in inappropriate situations. This includes using the default String type. Both the list and string syntax have been overloadable for a while, so using alternatives when necessary shouldn't be an issue. Understand the complexity of the data structure operations you are using and you will get fast code, laziness does not change this (although space usage can be hard to reason about).

The benefits of laziness is difficult to appreciate if you are not used to it. For a great example of the benefits it brings, please read this:

http://augustss.blogspot.co.uk/2011/05/more-points-for-lazy-...

Re:Rust as a gateway drug to Haskell by verandaguys_alt on Wednesday June 14, 2017 @10:20AM (#14552892)
While I've found that Haskell's laziness can often be worked around with appropriately-implemented memoization, it's an absolute PITA for anything that requires frequent hops into the IO monad (unsurprisingly). Historically, this has been a bottleneck for me that's prevented me from using Haskell in any major projects.

A Haskell port of a logging library I'd originally written in Python ended up being almost 2 orders of magnitude slower than CPython 3, and almost 3 orders of magnitude slower than PyPy3.

PyPy3 resulted in performance similar to a barely-optimized C port.

Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @11:46AM (#14553558)
Do you have source code? It sounds like you were writing unidiomatic Haskell.
Re:Rust as a gateway drug to Haskell by verandaguys_alt on Wednesday June 14, 2017 @04:05PM (#14555664)
I actually posted the port on the Code Review SE, where (after almost a month of silence), someone stepped up and offered a CFFI solution.

https://codereview.stackexchange.com/questions/157118/a-port...

Re:Rust as a gateway drug to Haskell by vmchale on Wednesday June 14, 2017 @08:21PM (#14557053)
You might have better luck with the fast-logger library, for one. I'd also suggest using ansi-wl-pprint, which would work on Windows and also probably be faster than string concatenation (which is just plain bad in Haskell).

As was pointed out, GHC is calling getCurrentTime too often. If you take advantage of GHC's laziness, the value will stay valid longer. I assume that is what fast-logger does.

https://hackage.haskell.org/package/fast-logger

Re:Rust as a gateway drug to Haskell by brianberns on Wednesday June 14, 2017 @09:17AM (#14552458)
You might want to consider F# as well. It supports both lazy and greedy functional programming very nicely.
Re:Rust as a gateway drug to Haskell by Gackle_Murderer on Wednesday June 14, 2017 @02:07PM (#14554679)
You might like Idris. Not nearly as mature as Haskell, but definitely as powerful, with much more reasonability when it comes to performance, thanks to eager evaluation.
Re:Rust as a gateway drug to Haskell by crimsonalucard on Wednesday June 14, 2017 @10:55AM (#14553182)
It's not just laziness. Functional programming is what happens to the universe when you eliminate the concept of Time. It is a mega abstraction over the what's really going on under the hood.

However we live in the real world and in the real world you cannot eliminate the concept of time, even in an abstraction such as functional programming. Therefore Functional programming is an utter lie.

Reasoning about the performance of a functional program is to peer through the lie and "reintroduce" time into this abstraction. This is why it it notoriously hard for functional programs to be reasoned about. Procedural programs are much more better for this in that regard.

Re:Rust as a gateway drug to Haskell by tome on Wednesday June 14, 2017 @10:59AM (#14553215)
This is utter nonsense.

Everything you wrote is somewhere between 90° and 180° wrong.

Re:Rust as a gateway drug to Haskell by crimsonalucard on Wednesday June 14, 2017 @11:18AM (#14553356)
I'm totally correct. You are completely unaware of what's going on. We can discuss this logically in the comments, you'll see. It's not going to pretty for you as my arguments will pick you apart piece by piece.
Re:Rust as a gateway drug to Haskell by hxegon on Wednesday June 14, 2017 @01:16PM (#14554218)
saying "I'm going to destroy your argument with logic" is not the same thing as actually destroying someone's argument with logic.
Re:Rust as a gateway drug to Haskell by crimsonalucard on Wednesday June 14, 2017 @01:53PM (#14554558)
Logically speaking, I never equated the two statements. It's up to him whether he wants to engage in a debate. Additionally, this guy just replied saying I was 180 degrees off angle without any explanation, how polite.
Re:Rust as a gateway drug to Haskell by akhilcacharya on Wednesday June 14, 2017 @12:36PM (#14553883)
>Functional programming is what happens to the universe when you eliminate the concept of Time.

I've heard this a lot but still can't find a good code example to illustrate this. Any help?

Re:Rust as a gateway drug to Haskell by haskellandchill on Wednesday June 14, 2017 @06:16PM (#14556542)
The statement makes no sense. See FRP for a take on how to handle time-varying behavior.
Re:Rust as a gateway drug to Haskell by crimsonalucard on Wednesday June 14, 2017 @11:44PM (#14557797)
It does make sense. Man of course whenever the functional paradigm switches to IO things change. The functional program needs to have an exception somewhere or nothing gets done. I'm talking about the functional part of functional programming, not how the IO monad is implemented.
Re:Rust as a gateway drug to Haskell by crimsonalucard on Thursday June 15, 2017 @01:29PM (#14562428)
Let me make my statement clearer. The FRP loop has a part that is not pure (IO). This is where time enters the picture. FRP is not 100% functional, no functional programming language is... but if you look at the functional part of a functional programming language you will see that it is immutable.
Re:Rust as a gateway drug to Haskell by crimsonalucard on Wednesday June 14, 2017 @11:49PM (#14557814)
Immutability is equivalent of eliminating time. To be unchanging is to be timeless.