<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>paldepind</title><link>https://monoid.dk/</link><description>Recent content on paldepind</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Sun, 06 May 2018 14:25:45 +0100</lastBuildDate><atom:link href="https://monoid.dk/index.xml" rel="self" type="application/rss+xml"/><item><title>How can List be faster than native arrays?</title><link>https://monoid.dk/post/how-can-list-be-faster-than-native-arrays/</link><pubDate>Sun, 06 May 2018 14:25:45 +0100</pubDate><guid>https://monoid.dk/post/how-can-list-be-faster-than-native-arrays/</guid><description>&lt;p>&lt;a href="https://github.com/funkia/list">List&lt;/a> is an extremely fast immutable
list that can be used as an alternative to native JavaScript arrays.
Since List is immutable it is made for &lt;em>functional programming&lt;/em>. For
this use case it is often much faster than native JavaScript arrays
and libraries that operate on arrays like Lodash and Ramda.&lt;/p>
&lt;p>&lt;a href="https://twitter.com/jeremylikness">Jeremy Likness&lt;/a> recently
&lt;a href="https://twitter.com/jeremylikness/status/992394166494814210">tweeted&lt;/a>
about List (thanks a lot). One of the things he mentioned was the
claim that List is faster than arrays. Several people responded with a
healthy skepticism to this statement. How can something be faster than
arrays which are native to JavaScript and highly optimized by the
JavaScript engines? The short answer is that by exploiting
immutability List can avoid a lot of unnececarry copying through
structural sharing. This blog post will go into more detail and show
how structural sharing leads to huge improvements in performance.&lt;/p>
&lt;h1 id="the-problem-with-arrays">The problem with arrays&lt;/h1>
&lt;p>In functional programming, we never mutate or change our
data-structures. Instead, all operations on data-structures that needs
to change something must return a &lt;em>new&lt;/em> version without modifying the
old one. An example of this is the &lt;code>concat&lt;/code> method on arrays. The code
&lt;code>arrayA.concat(arrayB)&lt;/code> changes neither &lt;code>arrayA&lt;/code> nor &lt;code>arrayB&lt;/code>. It
returns a brand new array.&lt;/p>
&lt;p>Arrays are stored in memory as a consequetive sequence of bits.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/array.svg" alt="Array">&lt;/p>
&lt;p>Therefore, when a pure function operates on arrays the only thing it
can do in order to return a new array is to &lt;em>copy the entire array&lt;/em>.
For instance, to append a single element to a list by using &lt;code>concat&lt;/code>
or Ramda&amp;rsquo;s &lt;code>append&lt;/code> the entire array that is being appended to must be
copied. As another example, to remove the first element of an array
one can write &lt;code>array.slice(1)&lt;/code>, use the function &lt;code>_.initial&lt;/code> from
Lodash, or &lt;code>R.init&lt;/code> from Ramda. All of these functions make a copy of
the entire slice. If the array is 1000 elements long the code will
construct a brand new array of length 999.&lt;/p>
&lt;p>When doing functional programming with arrays a lot of time is wasted
copying arrays all the time. This not only makes our code slower, it
also gives the garbage collector extra work because it has to free all
the memory again. We pay twice.&lt;/p>
&lt;h1 id="how-list-solves-the-problem">How List solves the problem&lt;/h1>
&lt;p>List is an implementation of an immutable data-structure called
relaxed radix balanced trees. Like most immutable data-structures it
uses a technique called &lt;em>structural sharing&lt;/em> to avoid the unnecessary
copying we saw with arrays. Internally a sequence of elements is
stored by List in a format that looks a bit like this.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>&lt;img src="https://monoid.dk/images/list.svg" alt="Internals of List">&lt;/p>
&lt;p>One way of looking at the above is that List stores elements in
several small chunks. Whenever we need to create a new list we can
reuse all the chunks that didn&amp;rsquo;t change. This type of reusing is
structural sharing. Arrays, on the other hand, store everything in one
big chunk so it&amp;rsquo;s not possible to use share anything when changing an
array.&lt;/p>
&lt;p>If we appended an element to the above list we would get a new list
that, internally, looked something like this.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/list-appended.svg" alt="List after appending">&lt;/p>
&lt;p>The dashed boxes represent the new list. Note how everything in the
old list is reused in the new list. This is one part of why List can
perform so well. Appending an element to a list takes essentially the
same time no matter how large a list we&amp;rsquo;re appending to. This can be
seen in benchmarks.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/append-plot.png" alt="Append plot">&lt;/p>
&lt;p>Appending an element to an array takes more and more time as the array
gets larger. For List the time is constant. Appending an element to a
list takes the same time on a list of length 10 as it does on a list
of length 10.000.&lt;/p>
&lt;p>This performance improving technique applies to a wide range of
operations. Sharing is useful for things such as changing a single
element in a list, inserting elements into a list, concatenating
lists, and slicing a list. The graph below compares the performance of
&lt;code>slice&lt;/code> between List and arrays.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/slice-plot.png" alt="Slice plot">&lt;/p>
&lt;p>Again, every time we want to change something in an array we must make
a copy of the entire array. But, to change something in a list we can
reuse large parts that can be shared between the new and the old list.&lt;/p>
&lt;p>Another aspect that makes List faster than native arrays is that many
methods on native arrays are actually quite slow. This applies to
&lt;code>map&lt;/code>, &lt;code>filter&lt;/code>, &lt;code>reduce&lt;/code>, and more. They have a lot of complexity
that slows them down. For instance
&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter">&lt;code>filter&lt;/code>&lt;/a>
must handle sparse arrays and must accommodate for the filtering
predicate mutating the array during the filter. These things are
required per the JavaScript specification and they slow down native
arrays. The graph below shows the performance of filtering a List
versus filtering an array.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/filter-plot.png" alt="Filter plot">&lt;/p>
&lt;h1 id="caveats">Caveats&lt;/h1>
&lt;p>Even though List is very fast across the board no data-structure can
be the fastest at everything. There are a few operations where List is
slower than native arrays. One of these is random accessing. I.e.
accessing arbitrary elements out of order. But, even in the few cases
where List is behind native arrays, it is not behind by much.&lt;/p>
&lt;p>Another caveat is that some functions in List are slower than arrays
for very small lists&amp;mdash;even though they scale better to larger lists.
This can be seen in the plot of &lt;code>slice&lt;/code> above. List&amp;rsquo;s &lt;code>slice&lt;/code> is a lot
faster on large lists but for small lists, it is slightly slower. This
is something that I&amp;rsquo;m planning to improve in the future.&lt;/p>
&lt;h1 id="conclusion">Conclusion&lt;/h1>
&lt;p>By using structural sharing List can implement a lot of operations in
a way that is much faster than what is possible with arrays. This
means that for most functional use cases using List will be faster
than arrays. However, that is only part of the reason why someone may
use List. Other benefits, that in many cases are more important, are
enforced immutability and the extensive API that List offers.&lt;/p>
&lt;p>For more information about List check it out on
&lt;a href="https://github.com/funkia/list">GitHub&lt;/a>. For more extensive
benchmarks see the &lt;a href="https://funkia.github.io/list/benchmarks/">benchmark
report&lt;/a>.&lt;/p></description></item><item><title>Behaviors and streams, why both?</title><link>https://monoid.dk/post/behaviors-and-streams-why-both/</link><pubDate>Fri, 12 May 2017 14:25:45 +0100</pubDate><guid>https://monoid.dk/post/behaviors-and-streams-why-both/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>Functional reactive programming (FRP) has historically included two
different abstractions over time: behavior and stream. Today most FRP
and FRP-inspired libraries only have a single abstraction over time.
This one abstraction is typically called &amp;ldquo;stream&amp;rdquo; or &amp;ldquo;observable&amp;rdquo;.&lt;/p>
&lt;p>People used to these libraries may wonder: Why do I need both behavior
and stream? I&amp;rsquo;m doing fine with just streams/observables. Asking that
is natural. In fact, when I wrote my first FRP library
&lt;a href="https://github.com/paldepind/flyd/">Flyd&lt;/a> I only included a single
abstraction over time. I thought it was simpler than having two
concepts.&lt;/p>
&lt;p>However, after digging deeper into FRP I came to see that one loses
something very crucial when not making a distinction between behaviors
and stream. What exactly that is is not obvious, however. In this blog
post, I will try to explain what it is.&lt;/p>
&lt;h1 id="what-is-the-difference-anyway">What is the difference anyway?&lt;/h1>
&lt;p>Both behaviors and streams represent things that happen or changes
over time. But still, they are very different. Visually this
difference looks like this.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/behaviorstream.svg" alt="Diagram of behavior and stream">&lt;/p>
&lt;p>Intuitively, a behavior is a value that changes over time. And a
stream is something that has occurrences at specific moments in time.
A behavior can be seen as a function over time. A stream, on the other
hand, is a list of events associated with their time of occurrence.&lt;/p>
&lt;p>To figure out whether something is conceptually a behavior or a stream
one can simply ask: Does this thing has a &amp;ldquo;current value&amp;rdquo; or does it
instead have a &amp;ldquo;last occurrence&amp;rdquo;? In the first case, it is a behavior
and in the later case a stream.&lt;/p>
&lt;p>The classic example is the mouse. Its position is a behavior while the
clicks of its buttons are streams. Here are a few additional examples:&lt;/p>
&lt;ul>
&lt;li>Sunset is a stream. It doesn&amp;rsquo;t have a current value but it does have
a last occurrence.&lt;/li>
&lt;li>The position of the sun is a behavior since it always has a current
value.&lt;/li>
&lt;li>The height of a tree is a behavior since it has a current value.&lt;/li>
&lt;li>Leaves falling off of a tree is a stream—we can tell when a
leave last fell off the tree.&lt;/li>
&lt;/ul>
&lt;p>As you can see things in the real world are either a behavior or a
stream. So it seems natural that our programs should be able to
express the difference as well.&lt;/p>
&lt;h1 id="how-can-one-get-away-without-both">How can one get away without both?&lt;/h1>
&lt;p>Most libraries that only have a single abstraction over time has one
that is much more like a stream than like a behavior. They pretty much
just lack behavior altogether. Whenever people say things such as &amp;ldquo;an
observable is like a list over time&amp;rdquo; they are talking about streams.
They can&amp;rsquo;t be talking about a behavior because a behavior is a
function over time.&lt;/p>
&lt;p>How do they compensate for the lack of behaviors? Well, essentially
one just &amp;ldquo;interprets&amp;rdquo; a stream as a behavior. The image below
illustrates this.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/stream-as-behavior.svg" alt="Stream as behavior">&lt;/p>
&lt;p>On the left, we see an actual behavior and on the left we see a stream
interpreted as a behavior. We simply remember the last occurrence and
takes it to be the &amp;ldquo;current value&amp;rdquo; of the stream. Some libraries
remember event occurrences like this by default while other have a
variant of their stream/observable that does. So even though some
libraries doesn&amp;rsquo;t recognize behaviors as a separate thing they still
need features to fill in the gap.&lt;/p>
&lt;p>The crucial question now is: What are the downsides to only supporting
this &amp;ldquo;fake&amp;rdquo; behavior? What are the benefits of having an actual
behavior separate from streams? Hang tight, because that is what the
rest of this blog posts covers.&lt;/p>
&lt;h1 id="it-is-precise-and-explicit">It is precise and explicit&lt;/h1>
&lt;p>When programming it is generally good practice to use types that are
as precise as possible. For instance, even though we could, in theory,
represent all numbers as strings, we don&amp;rsquo;t. Even when programming in a
dynamic language like JavaScript it is a good idea to have an idea
about which types of values your variables contain. For instance, you
may be thinking things like &amp;ldquo;this variable is a number&amp;rdquo; and &amp;ldquo;this
variable is a string&amp;rdquo;.&lt;/p>
&lt;p>Likewise, when programming with FRP it is beneficial to know which
things in a program are behaviors and which things in a program are
streams. Conceptually these are two different things! Asking yourself
whether a certain phenomenon is a behavior or a stream is highly
useful. It is a useful mental process that makes you more aware of
what exactly you are dealing with. Making a distinction between
behavior and streams gives us richer vocabulary. If your program also
makes the distinction this richness will translate into programs that
are more expressive and precise about they are talking about.&lt;/p>
&lt;p>On the other hand, expressing both behaviors and streams with a single
abstraction makes it is impossible to make a clear distinction. That
can create confusion and inhibit features and performance because two
separate concerns are mixed into a single abstraction.&lt;/p>
&lt;h1 id="it-prevents-mistakes">It prevents mistakes&lt;/h1>
&lt;p>Libraries that makes a distinction between behaviors and streams can
prevent many errors from happening.&lt;/p>
&lt;p>For instance, a behavior always has a current value. But, streams
doesn&amp;rsquo;t. This means that when a stream is used as a behavior the user
will have to remember to supply some initial occurrence to the stream.
If the user forgets that, a bug has been introduced.&lt;/p>
&lt;p>A library that recognizes behaviors can know exactly when it is
dealing with such. When a current value is expected the API will
require a behavior. And the API makes it impossible to create
behaviors that don&amp;rsquo;t have an initial value. This completely
eliminates errors where initial values are missing.&lt;/p>
&lt;p>Another thing we can prevent with explicit behaviors is meaningless
operations. There are a bunch of operations that we can apply to a
stream that does not make sense on a behavior. Likewise, there are
operations that make sense on a behavior but not on a stream.
Libraries that can&amp;rsquo;t tell the difference between behaviors and streams
can&amp;rsquo;t prevent people from carrying out operations that don&amp;rsquo;t make
sense.&lt;/p>
&lt;p>As an example, it makes sense to combine two streams by merging their
occurrences. Visually it looks like this&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/stream-combine.svg" alt="Diagram of combining streams">&lt;/p>
&lt;p>However, combining two behaviors in this manner doesn&amp;rsquo;t make any
sense. But still, libraries that don&amp;rsquo;t support behaviors can&amp;rsquo;t prevent
it. We may end up merging the position of one object with the position
of another object. This will a result that no longer makes sense
understood as a behavior. This can lead to code that does &amp;ldquo;shady&amp;rdquo; or
confusing things by exploiting that behaviors are represented as
stream.&lt;/p>
&lt;h1 id="it-is-a-higher-abstraction">It is a higher abstraction&lt;/h1>
&lt;p>Some behaviors have multiple representations as a streams. For
instance, these two streams represent the exact same behavior.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/equivalent-streams.svg" alt="Diagram of combining streams">&lt;/p>
&lt;p>Clearly, these &amp;ldquo;extra&amp;rdquo; occurrences don&amp;rsquo;t change the streams meaning as
a behavior. But a stream-only library doesn&amp;rsquo;t know that. Since the
library doesn&amp;rsquo;t have the behavior abstraction but uses streams instead
its API necessarily exposes how many occurrences a steam is made of.
Even when it&amp;rsquo;s used as a behavior.&lt;/p>
&lt;p>When implementing a behavior, the API can be designed such that
&amp;ldquo;peeking into&amp;rdquo; the internal representation of a behavior in this
manner is impossible. The library knows when the user actually wants
to use a behavior. This allows for more optimizations since no
implementation details are exposed.&lt;/p>
&lt;p>For instance, when implementing behavior with a dependency graph only
actual changes in values have to be propagated. As an example of this,
let&amp;rsquo;s say a user writes the following:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-js" data-lang="js">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">flooredNumberBehavior&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">numberBehavior&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">Math&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">floor&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Clearly some changes to &lt;code>numberBehavior&lt;/code> won&amp;rsquo;t lead to a change in
&lt;code>flooredNumberBehavior&lt;/code>. Maybe an update flows down that changes
&lt;code>numberBehavior&lt;/code> from &lt;code>3.5&lt;/code> to &lt;code>3.8&lt;/code>. In this case an implementation
of behavior can recognize that nothing changes in
&lt;code>flooredNumberBehavior&lt;/code>. This allows it to simply stop propagating
changes down.&lt;/p>
&lt;p>This can lead to substantial improvements to performance as it
prevents needles re-computation. To , such an optimization can
never be done. Because someone might call a method like &lt;code>scan&lt;/code> later
that exposes the number of occurrences and not just changes in value.&lt;/p>
&lt;h1 id="it-allows-for-infinite-resolution-behaviors">It allows for infinite resolution behaviors&lt;/h1>
&lt;p>While the stream interpreted as behavior, we saw above, can represent some
behaviors it can&amp;rsquo;t represent all behaviors. Some behaviors it can only
crudely approximate. That is because a behavior can change &amp;ldquo;infinitely
often&amp;rdquo;. I.e. be continuous. An example of such a behavior is seen below.&lt;/p>
&lt;p>&lt;img src="https://monoid.dk/images/stream-approximation.svg" alt="Approximating behavior with stream">&lt;/p>
&lt;p>To the right, we have an attempt at approximating the behavior with a
stream. Clearly, such an approximation is lossy and imprecise.&lt;/p>
&lt;p>Being able to represent these types of behaviors with infinite
resolution is extremely beneficial. In particular, it is helpful when
writing programs that deal with things such as time and motion. Like
when implementing animations for instance.&lt;/p>
&lt;p>One may think that this problem can be avoided simply by using streams
with a resolution that is &amp;ldquo;good enough&amp;rdquo;. But the problem is not only
related to resolution. It is also a problem about composition.&lt;/p>
&lt;p>For instance, let&amp;rsquo;s say you want to implement an animation with
streams. You may think, I&amp;rsquo;ll just create a stream that has an
occurrence for each frame. Clearly, that resolution is good enough. But
consider what then happens if you combine two such streams. For
instance, you may have an &lt;code>x&lt;/code>-coordinate that changes every frame and a
&lt;code>y&lt;/code>-coordinate that does the same. If you combine those you get a
stream that changes twice every frame. That is pretty bad.&lt;/p>
&lt;p>With an FRP library that support continuous behaviors that problem does
not exist. You&amp;rsquo;d simply have a behavior for the &lt;code>x&lt;/code>-coordinate and one
for the &lt;code>y&lt;/code>-coordinate. Internally those will be represented in a way
that supports infinite resolution. Thus, when you combine them you
simply get a third behavior, also of infinite resolution.&lt;/p>
&lt;p>The above problem is similar to vector graphics vs. pixel graphics.
Vector graphics has infinite resolution. This means that we can, among
other things, zoom in and rotate without losing quality. Of course, at
some point, a vector image will have to be converted to pixels in
order to be displayed on the screen. But such a conversion only
happens at the very last step, after we have zoomed and rotated.
Similarly, when working with behaviors of infinite resolution all
operations on them happens to the internally infinite version. Only
for the purpose of showing them on the screen are they converted to a
format with the necessary resolution.&lt;/p>
&lt;h1 id="conclusion">Conclusion&lt;/h1>
&lt;p>We have seen some of the main benefits of recognizing that behaviors
and streams are two different things. It may up front seem like having
two abstractions is more complex that just one. But it turns out that
down the road it makes things much simpler and more powerful. In
general, programs that keep separate things separate are easier to
understand.&lt;/p></description></item><item><title>Introducing Jabz</title><link>https://monoid.dk/post/introducing-jabz/</link><pubDate>Wed, 04 Jan 2017 14:25:45 +0100</pubDate><guid>https://monoid.dk/post/introducing-jabz/</guid><description>&lt;h2 id="introduction">Introduction&lt;/h2>
&lt;p>Jabz is a new library aimed at implementing powerful abstractions in
JavaScript while being as practical as possible. It is hugely inspired
by Fantasy Land but is an attempt at achieving something more
convenient and with better performance.&lt;/p>
&lt;p>Jabz specifies the same abstractions as Fantasy Land. Functor, monad,
traversable, etc. Besides specifying these things it is also a library
that includes a common set of functions for working with the
abstractions, as well as often used implementations.&lt;/p>
&lt;p>I initially created Jabz to be a TypeScript implementation of common
structures satisfying the Fantasy Land specification, but along the
way I had some ideas that warranted a new specification. In
this blog post I will explain how Jabz&amp;rsquo;s specification of these
abstractions differ from Fantasy Land&amp;rsquo;s. I will assume that the reader
is familiar with Fantasy Land and the related abstractions.&lt;/p>
&lt;p>Jabz can &lt;a href="https://github.com/Funkia/jabz">be found on GitHub&lt;/a>.&lt;/p>
&lt;h2 id="goals">Goals&lt;/h2>
&lt;p>My overlaying goal was to create a specification and a library that
achieved the following properties:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>Convenience&lt;/strong>. Using the abstractions should be as convenient as
possible from an end users perspective. Developer ergonomics should
be highly valued.&lt;/li>
&lt;li>&lt;strong>Performance&lt;/strong>. Inefficient abstractions are useless abstractions.
The specification should give implementations the necessary room for
creating performant implementation.&lt;/li>
&lt;li>&lt;strong>Power&lt;/strong>. The abstractions should be as powerful as can be.
That is, they should have as many features and support as many use
cases as possible.&lt;/li>
&lt;/ul>
&lt;p>To achieve the above, the one thing I traded away was simplicity of
specification. Fantasy Land is a simple and elegant specification that
only concerns itself with what is strictly essential. Jabz, in
comparison, is more voluminous. I do, however, believe the trade-off is
worth it.&lt;/p>
&lt;p>Below I will describe the major general differences between Jabz
and Fantasy Land. After that I will cover some of the specific
abstractions and how they are different in Jabz.&lt;/p>
&lt;h2 id="non-prefixed-method-names">Non-prefixed method names&lt;/h2>
&lt;p>Jabz uses non-prefixed method names. To be a functor an object must
have a &lt;code>map&lt;/code> method. This is in contrast to Fantasy Land, where a
Functor must have a method named &lt;code>fantasy-land/map&lt;/code>. Jabz uses
non-prefixed method names primarily since they&amp;rsquo;re more convenient and
convenience is one of the primary goals.&lt;/p>
&lt;p>One argument for prefixed method names in Fantasy Land is that then
libraries can implement the specification even if they currently have
methods with the same name that don&amp;rsquo;t behave according to the
specification. In my opinion, disallowing that is a &lt;em>good thing&lt;/em>.
Having a &lt;code>map&lt;/code> method that does one thing and a &lt;code>fantasy-land/map&lt;/code>
method that does another thing is a source of confusion. It creates
situations where &lt;code>map(f,foo)&lt;/code> might do something different than
&lt;code>foo.map(f)&lt;/code>.&lt;/p>
&lt;p>Requiring non-prefixed methods ensures that if a structure supports
Jabz it is not allowed to have, for instance, an improper &lt;code>map&lt;/code>
method. Jabz demands more from implementations. But it also means that
users can rely on implementations having easily accessible methods
that behave as expected.&lt;/p>
&lt;h2 id="beyond-minimal-complete-definitions">Beyond minimal complete definitions&lt;/h2>
&lt;p>Each abstraction specified by Fantasy Land is defined as a set of
methods. For instance, foldable is defined by a &lt;code>reduce&lt;/code> method (I
prefer the name &lt;code>foldr&lt;/code> so I&amp;rsquo;ll use that going forward).&lt;/p>
&lt;p>Part of the reason why the foldable abstraction is useful is that,
building on top of this single method, we can create many more. For
instance, we can derive a function for getting the number of elements in
any foldable.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">size&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">foldable&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">foldable&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">foldr&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nx">n&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This is an example of a derived method.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>A &lt;em>derived method&lt;/em> is one that can be defined in terms of other, often
more fundamental, methods.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>In all cases the number of methods that Fantasy Land requires by its
implementations are as few as possible. What it defines constitutes a
minimal complete definition of the given abstraction.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>A &lt;em>minimal complete definition&lt;/em> is a set of methods describing an
abstraction where none of the methods can be derived in terms of the other.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>However the &lt;code>size&lt;/code> function derived above is problematic. It takes
&lt;code>O(n)&lt;/code> time, where &lt;code>n&lt;/code> is the size of the foldable. Most data
structures maintains a size that can be obtained in constant time.
Thus, for these data structures using the generalized &lt;code>size&lt;/code> function incurs a
prohibitively expensive overhead. In practice this means that our
abstracted &lt;code>size&lt;/code> function, sadly, isn&amp;rsquo;t all too useful. But with the
Fantasy Land specification we can&amp;rsquo;t do better.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>An abstraction that is unnecessarily costly with regards to
performance is often impractical.&lt;/p>
&lt;!-- raw HTML omitted -->
&lt;p>Haskell solves this issue by including a &lt;code>size&lt;/code> method as part of the
&lt;code>Foldable&lt;/code> type class. Jabz takes a similar approach by specifying
that foldables must have a &lt;code>size&lt;/code> method. This means that
implementations of foldable can optionally implement a performant
version of &lt;code>size&lt;/code>. Alternatively, they can choose to rely on the
default, slower one that Jabz provides.&lt;/p>
&lt;p>This is a general trend: where Fantasy Land only contains minimal
complete definitions in the specification, Jabz on the contrary
includes any method that some specific implementations might benefit
from implementing in a specialized way.&lt;/p>
&lt;h2 id="supported-by-code">Supported by code&lt;/h2>
&lt;p>The fact that Jabz specifies a lot more methods than Fantasy Land places
an extra burden on implementations. Therefore these are meant to be
created with support from the library. This makes it very convenient
to implement the abstractions.&lt;/p>
&lt;p>Jabz achieves this by offering functions that take classes and ensures
that they have the necessary methods. These functions only require
that some minimal complete definition is present. Beyond that, missing
methods will automatically be filled in with default derived
implementations.&lt;/p>
&lt;p>For instance, Jabz requires functors to have both a &lt;code>map&lt;/code> and a &lt;code>mapTo&lt;/code>
method. But since &lt;code>mapTo&lt;/code> can be derived from &lt;code>map&lt;/code>, an implementation
doesn&amp;rsquo;t have to specify it. A functor can be implemented like this&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="err">@&lt;/span>&lt;span class="nx">functor&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">class&lt;/span> &lt;span class="nx">MyFunctor&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">f&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The &lt;code>functor&lt;/code> function ensures that &lt;code>MyFunctor&lt;/code> satisfies the functor
specification. It automatically installs a default derived &lt;code>mapTo&lt;/code> on
&lt;code>MyFunctor&lt;/code>s prototype. Each abstraction in Jabz comes with a matching
function for creating implementations. Using them as a decorators, as
above, looks nice but is of course not required. Decorators are just
fancy syntax for applying functions to classes.&lt;/p>
&lt;h2 id="monoid-with-nicely-named-methods">Monoid with nicely named methods&lt;/h2>
&lt;p>Fantasy Land monoids must have the two methods &lt;code>empty&lt;/code> and &lt;code>concat&lt;/code>.
These names make sense for the list instance of monoid where &lt;code>empty&lt;/code>
gives the empty list and &lt;code>concat&lt;/code> does list concatenation. However, for
other instances they are very awkward. One example is the &lt;code>Max&lt;/code> monoid
whose elements are numbers and where infinity is the identity element
and the merge operation returns the minimum of two numbers. In this
case &lt;code>empty&lt;/code> is a very counterintuitive name for a function that
returns infinity.&lt;/p>
&lt;p>In Jabz the monoid methods are instead called &lt;code>identity&lt;/code> and
&lt;code>combine&lt;/code>. These names should be fairly easy to understand while
ensuring that no specific instances of Monoid ends up with
non-intuitive names. The idea is that abstract concepts should have
abstract names.&lt;/p>
&lt;h2 id="speedy-applicatives">Speedy applicatives&lt;/h2>
&lt;p>If we have a function that takes one argument, we can apply it to a
functor with &lt;code>map&lt;/code>. However, we can&amp;rsquo;t apply a function that takes &lt;code>n&lt;/code>
arguments to &lt;code>n&lt;/code> functors. That is what applicative was made for.&lt;/p>
&lt;p>If &lt;code>f&lt;/code> is a function from three arguments and &lt;code>a&lt;/code>, &lt;code>b&lt;/code> and &lt;code>c&lt;/code> are
applicatives, we can use Fantasy Lands &lt;code>ap&lt;/code> like this to apply &lt;code>f&lt;/code> to
the applicatives:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">c&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">b&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">ap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">map&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">of&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">f&lt;/span>&lt;span class="p">))));&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This an awkward way of applying a function to two applicatives. So
we&amp;rsquo;d probably abstract the pattern into a function called &lt;code>lift&lt;/code>. It
might work like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">lift&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">f&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">b&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">c&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>However, there is a problem here. Let&amp;rsquo;s say &lt;code>f&lt;/code> is any function taking
&lt;code>n&lt;/code> arguments. If we only have the methods &lt;code>ap&lt;/code> and &lt;code>of&lt;/code>, there is no
way to apply &lt;code>f&lt;/code> to &lt;code>n&lt;/code> applicatives without currying &lt;code>f&lt;/code> and calling
the curried function &lt;code>n&lt;/code> times. This hurts performance pretty badly.
In most cases it may not matter. But why have applicatives with an
unnecessary performance overhead?&lt;/p>
&lt;p>Unplaced with the situation, Jabz allows applicatives to bring their
own &lt;code>lift&lt;/code> method. &lt;code>lift&lt;/code> can be derived, so if they don&amp;rsquo;t they will
be given the default slow one. This has the significant advantage that
for a specific structure it is often easy to implement &lt;code>lift&lt;/code> so that
the function to lift does not have to be curried and is only applied
once.&lt;/p>
&lt;p>To see what the difference can be in practice I&amp;rsquo;ve created a small
benchmark that compares lifting a function over Jabz&amp;rsquo;s &lt;code>Maybe&lt;/code> with
&lt;code>lift&lt;/code> and with &lt;code>ap&lt;/code>. &lt;a href="https://github.com/Funkia/jabz/blob/master/benchmark/aplift.suite.js">The source code can be found here&lt;/a>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">-------------------- &lt;span class="sb">`&lt;/span>ap&lt;span class="sb">`&lt;/span> vs &lt;span class="sb">`&lt;/span>lift&lt;span class="sb">`&lt;/span> on &lt;span class="sb">`&lt;/span>Maybe&lt;span class="sb">`&lt;/span> --------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">lift 9150491.49 op/s ± 4.45% &lt;span class="o">(&lt;/span>&lt;span class="m">68&lt;/span> samples&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ap 1665864.27 op/s ± 1.31% &lt;span class="o">(&lt;/span>&lt;span class="m">85&lt;/span> samples&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">---------------------------- Best: lift ----------------------------
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Of course this is a small micro-benchmark but it does show that
lifting a function with &lt;code>ap&lt;/code> is expensive. Since lifting is pretty
much what applicatives are good for, this means that Jabz applicatives
come with no overhead, whereas Fantasy Land&amp;rsquo;s come with an inherent
slowdown.&lt;/p>
&lt;h2 id="monads-with-do-notation">Monads with do-notation&lt;/h2>
&lt;p>When Haskell began using monads, do-notation was introduced along with
them. The reason is simple: monads are not very convenient to work
with without do-notation. Hence, I believe that in order to make monads
practically useful in JavaScript, we need a substitute for do-notation.
Fortunately, such a thing is possible by using JavaScript generators. I
first saw this brilliant idea in the
library &lt;a href="https://github.com/russellmcc/fantasydo">Fantasy Do&lt;/a>. Jabz
implements this and calls it &amp;ldquo;go-notation&amp;rdquo;—because &lt;code>do&lt;/code> is a reserved
word in JavaScript. It might stand for &amp;ldquo;&lt;strong>G&lt;/strong>enerato-d&lt;strong>O&lt;/strong>-notation&amp;rdquo;.
With this technique we can get do-notation like this.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">value&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">go&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">function&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">yield&lt;/span> &lt;span class="nx">someFunctionReturningAMonad&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">yield&lt;/span> &lt;span class="nx">iAlsoReturnAMonad&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">doSomethingWithTheBoundValues&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>which is comparable to&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-haskell" data-lang="haskell">&lt;span class="line">&lt;span class="cl">&lt;span class="nf">value&lt;/span> &lt;span class="ow">=&lt;/span> &lt;span class="kr">do&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">someFunctionReturningAMonad&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">b&lt;/span> &lt;span class="ow">&amp;lt;-&lt;/span> &lt;span class="n">iAlsoReturnAMonad&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">return&lt;/span> &lt;span class="n">doSomethingWithTheBoundValues&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">b&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>So the string &amp;ldquo;&lt;code>= yield&lt;/code>&amp;rdquo; should be read as Haskell&amp;rsquo;s &amp;ldquo;&lt;code>&amp;lt;-&lt;/code>&amp;rdquo;.&lt;/p>
&lt;p>This form of do-notation is immensely useful. But due to some
unfortunate technical limitations of generators, the &lt;code>do&lt;/code> function has
to behave very differently for monads that invoke the callback to
&lt;code>chain&lt;/code> several times and those that only invoke it once. Therefore,
Fantasy Do exports two different functions for these two cases. This
seems like a minor inconvenience, but it breaks the abstraction. A
single application of do-notation can no longer work for all monads as
it should.&lt;/p>
&lt;p>Let&amp;rsquo;s say we have an interface for monads with a &lt;code>random&lt;/code> method. The
&lt;code>random&lt;/code> method takes two integers and returns, in the monad, a
random integer between the two. Then we might write code like this:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">veryRandom&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="k">do&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="kd">function&lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">yield&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">random&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">b&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">yield&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">random&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">n&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">n&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">n&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">m&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="k">of&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">a&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="nx">b&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>The example is fairly silly, but the point is that &lt;code>veryRandom&lt;/code> should
work for &lt;em>any&lt;/em> monad &lt;code>m&lt;/code> that has a &lt;code>random&lt;/code> method. One monad that
might implement this is &lt;code>IO&lt;/code>, which would actually generate a random
variable. Another candidate is the non-determinism monad, aka. the
list monad which would instead return a list of values in the given
range. But since &lt;code>IO&lt;/code> only calls its &lt;code>chain&lt;/code> parameter once, and &lt;code>List&lt;/code>
calls it several times, Fantasy Do would require us to use two
different types of do-notation.&lt;/p>
&lt;p>The end result is that code which should work for all monads ends up
only working for some monads. This breaks the abstraction. To fix this,
Jabz simply requires all monads to have a &lt;code>multi&lt;/code> property. The
property declares whether or not the monad invokes the callback to
&lt;code>chain&lt;/code> multiple times. This small addition to the specification makes
completely general do-notation possible, which in turn makes monads a
lot more useful.&lt;/p>
&lt;h2 id="foldable">Foldable&lt;/h2>
&lt;p>Foldables in Jabz benefits significantly from the inclusion of more
methods in the specification. But I&amp;rsquo;ve talked about that already. So
let&amp;rsquo;s instead look at how Jabz regains some power that was otherwise
lost to the fact that JavaScript isn&amp;rsquo;t lazy.&lt;/p>
&lt;p>Consider the aforementioned &lt;code>find&lt;/code>.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kd">function&lt;/span> &lt;span class="nx">find&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">predicate&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">foldable&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="nx">foldable&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">foldr&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">e&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">a&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nx">predicate&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">?&lt;/span> &lt;span class="nx">just&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">e&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="nx">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">nothing&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Had we coded this nifty function in Haskell, execution would have
stopped as soon as an element in the foldable satisfying the predicate
had been found. So is the beauty of laziness. JavaScript, on the other
hand, is a bit of a workaholic, so the actual function above would
always iterate over the entire foldable. In many cases, that will be a
lot of wasted effort.&lt;/p>
&lt;p>Jabz remedies the situation by adding &lt;code>shortFoldr&lt;/code> and &lt;code>shortFoldl&lt;/code> to
its foldable specification. They are like the normal folds except that
the accumulator function has to return a value wrapped in an
&lt;code>Either&lt;/code>. &lt;code>right&lt;/code> means &amp;ldquo;keep going&amp;rdquo; and &lt;code>left&lt;/code> means &amp;ldquo;pull the breaks,
I&amp;rsquo;m done&amp;rdquo;. Both of these are deriveable, but implementations will have
to implement them to get the benefits of short-circuiting.&lt;/p>
&lt;p>This makes it feasible to implement quite a bunch of additional derived
functions compared to what only a strict right fold gives us. Examples
are &lt;code>find&lt;/code>, &lt;code>findLast&lt;/code>, &lt;code>take&lt;/code> and &lt;code>any&lt;/code>.&lt;/p>
&lt;p>Additionally, this also means that infinite data structures can be used
with Jabz&amp;rsquo;s foldable. In fact, Jabz ships with a simple infinite lazy
list.&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="nx">take&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">5&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">map&lt;/span>&lt;span class="p">((&lt;/span>&lt;span class="nx">n&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="nx">n&lt;/span> &lt;span class="o">*&lt;/span> &lt;span class="nx">n&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nx">naturals&lt;/span>&lt;span class="p">);&lt;/span> &lt;span class="c1">//=&amp;gt; [0, 1, 4, 9, 16]
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here &lt;code>naturals&lt;/code> is an infinite list of the natural numbers. First we
square them with &lt;code>map&lt;/code> and then we take the first five with &lt;code>take&lt;/code>.
This is possible since &lt;code>take&lt;/code> utilizes the &lt;code>shortFoldl&lt;/code> method on
foldables.&lt;/p>
&lt;h2 id="conclusion">Conclusion&lt;/h2>
&lt;p>We&amp;rsquo;ve covered some of the main differences between Jabz and Fantasy
Land. I hope I&amp;rsquo;ve convinced you that Jabz brings some interesting
ideas to the table. Especially in terms of creating low-overhead
abstractions with as many features as one can squeeze out of the them.&lt;/p>
&lt;p>Jabz is still far from finished. As a specification Fantasy Land is
more comprehensive. Jabz currently only specifies functor,
applicative, monad, foldable and traversable. And while it does
provide both a healthy set of utility function for working with the
abstractions and some commonly used implementations of the
specification there is still a lot to add. Contributions and feedback
is much appreciated.&lt;/p>
&lt;p>The library can &lt;a href="https://github.com/Funkia/jabz">be found on Gitub&lt;/a>.&lt;/p></description></item></channel></rss>