🎨 elm-format
This commit is contained in:
69
part9/tests/elm-stuff/packages/elm-lang/lazy/2.0.0/README.md
vendored
Normal file
69
part9/tests/elm-stuff/packages/elm-lang/lazy/2.0.0/README.md
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# Laziness in Elm
|
||||
|
||||
This package provides the basic primitives for working with laziness in Elm.
|
||||
|
||||
|
||||
# Motivating Example
|
||||
|
||||
Maybe you have 100 different graphs you want to show at various times, each
|
||||
requiring a decent amount of computation. Here are a couple ways to handle
|
||||
this:
|
||||
|
||||
1. Compute everything up front. This will introduce a delay on startup, but
|
||||
it should be quite fast after that. Depending on how much memory is needed
|
||||
to store each graph, you may be paying a lot there as well.
|
||||
|
||||
2. Compute each graph whenever you need it. This minimizes startup cost and
|
||||
uses a minimal amount of memory, but when you are flipping between two
|
||||
graphs you may be running the same computations again and again.
|
||||
|
||||
3. Compute each graph whenever you need it and save the result. Again, this
|
||||
makes startup as fast as possible fast, but since we save the result,
|
||||
flipping between graphs becomes much quicker. As we look at more graphs
|
||||
we will need to use more and more memory though.
|
||||
|
||||
All of these strategies are useful in general, but the details of your
|
||||
particular problem will mean that one of these ways provides the best
|
||||
experience. This library makes it super easy to use strategy #3.
|
||||
|
||||
|
||||
# Pitfalls
|
||||
|
||||
**Laziness + Time** —
|
||||
Over time, laziness can become a bad strategy. As a very simple example, think
|
||||
of a timer that counts down from 10 minutes, decrementing every second. Each
|
||||
step is very cheap to compute. You subtract one from the current time and store
|
||||
the new time in memory, so each step has a constant cost and memory usage is
|
||||
constant. Great! If you are lazy, you say “here is how you would subtract
|
||||
one” and store that *entire computation* in memory. This means our memory
|
||||
usage grows linearly as each second passes. When we finally need the result, we
|
||||
might have 10 minutes of computation to run all at once. In the best case, this
|
||||
introduces a delay that no one *really* notices. In the worst case, this
|
||||
computation is actually too big to run all at once and crashes. Just like with
|
||||
dishes or homework, being lazy over time can be quite destructive.
|
||||
|
||||
**Laziness + Concurrency** —
|
||||
When you add concurrency into the mix, you need to be even more careful with
|
||||
laziness. As an example, say we are running expensive computations on three
|
||||
worker threads, and the results are sent to a fourth thread just for rendering.
|
||||
If our three worker threads are doing their work lazily, they
|
||||
“finish” super quick and pass the entire workload onto the render
|
||||
thread. All the work we put into designing this concurrent system is wasted,
|
||||
everything is run sequentially on the render thread! It is just like working on
|
||||
a team with lazy people. You have to pay the cost of coordinating with them,
|
||||
but you end up doing all the work anyway. You are better off making things
|
||||
single threaded!
|
||||
|
||||
|
||||
## Learn More
|
||||
|
||||
One of the most delightful uses of laziness is to create infinite streams of
|
||||
values. Hopefully we can get a set of interesting challenges together so
|
||||
you can run through them and get comfortable.
|
||||
|
||||
For a deeper dive, Chris Okasaki's book *Purely Functional Data Structures*
|
||||
and [thesis](http://www.cs.cmu.edu/~rwh/theses/okasaki.pdf)
|
||||
have interesting examples of data structures that get great
|
||||
benefits from laziness, and hopefully it will provide some inspiration for the
|
||||
problems you face in practice.
|
||||
|
||||
Reference in New Issue
Block a user