~zainab/blog

40e76d367e9268aa1bcfcb1e08e750bfa9fcf9cf — zainab-ali 11 months ago 604aa7f
Fix typos
M src/chapters/fs2/introduction.html.pm => src/chapters/fs2/introduction.html.pm +1 -55
@@ 1,59 1,5 @@
#lang pollen

◊todo{
==Scope==
 - To provide an example use case for writing custom stream
 transformations
 - To walk through experiments with the fs2 Pull API

==Reader’s Aim==
To be able to write a custom stream transformation using fs2

==Not the reader’s aim==
To understand how pulls are implemented. Pulls may as well be magic.
To correlate pulls with other functional programming concepts
(e.g. free monads, DSLs)

==Out of Scope==
The reader may like these, but we won’t include them.
 - Chunking
 - Resource handling

==Prerequisites==
 - Familiarity with streams, building streams and combinators
 - Some familiarity with effects

==Next steps==
Things the reader can do next
 - Read the fs2 codebase of pulls. Attempt to implement some basic pulls.

Parts to change:
Should we reduce the dependency on cats-effect by removing Queue and
adding Ref instead? Ref is simpler to reason about for someone
unfamiliar with CE. And CE knowledge isn’t really necessary for this.

That would mean we’d need to have a fixed stream of dough (let’s say 3
rolls) and would write a pipe to enqueue our remaining dumplings in
the fridge.

We wouldn’t need to use effects at all (Pull.eval). This would lead
nicely into an article about what pulls mean.

If we do remove the infinite streaming, we can also reduce the
complexity of the production line. Instead we can have a simple
‘takeThrough’ pull. We’d just need a finite stream in the
beginning.

This would reduce the combinators we’d introduce in the beginning,
leaving only the ones we care about (notably Stream.apply, flatMap and
take).

==Initial notional model==
 - Streams are infinite data
 - They can only be built using fs2’s Stream.apply methods
 - They can only be transformed using fs2’s combinators
}

◊p{
When most people think of streaming problems, they think of HTTP
servers, event queues, or terabytes of data. Personally, I think


@@ 100,7 46,7 @@ them, are Chinese dumplings. They consist of a thin skin of dough
usually filled with pork and cabbage (but chicken, prawn or mushroom
all make decent fillings) and delicately folded. They can be cooked
many ways, but personally I prefer to boil them and douse them in soy
sauce and chili oil,, after which they become delicious warming packages.}
sauce and chili oil, after which they become delicious warming packages.}

◊p{Making jiaozi is a ◊external-link[#:href "https://thewoksoflife.com/pork-chive-dumplings/"]{laborious multi-stage process}.
The dough should be made from scratch, then rolled into logs, cut into

M src/chapters/fs2/overview.html.pm => src/chapters/fs2/overview.html.pm +5 -4
@@ 63,12 63,13 @@ take).
◊item{How fs2 own transformations, such as ◊code-inline{take}, are built.}
}

◊headline2{You should already}
◊headline2{I assume you know}

◊items{
◊item{Know how to build streams with the ◊code-inline{fs2.Stream} datatype.}
◊item{Be able to use stream transformations such as ◊code-inline{take}.}
◊item{Be vaguely familiar with the cats effect ◊code-inline{IO} datatype.}
◊item{How to build streams with the ◊code-inline{fs2.Stream} datatype.}
◊item{How to use stream transformations such as ◊code-inline{take}.}
◊item{A bit about the cats effect ◊code-inline{IO} datatype, to the
extent that you can create and run an ◊code-inline{IO}.}
}

◊p{You’ll get the most out of this if you’ve extensively used fs2, but

M src/chapters/fs2/pulls.html.pm => src/chapters/fs2/pulls.html.pm +4 -4
@@ 203,10 203,10 @@ The output type is ◊code-inline{INothing}, meaning this pull doesn’t output 
}

◊item{
The result is an ◊code-inline{Option[(String, Stream[Nothing, String])]}. It may contain a single value — the first value in the
The result is a mouthful of ◊code-inline{Option[(String, Stream[Nothing, String])]}. It may contain a single value — the first value in the
  stream — and the remaining stream. If there are no more values to
  emit, the result is ◊code-inline{None}. If you’ve familiar with
  ◊code-inline{uncons} on lists, this should ring a bell. 
  emit, the result is ◊code-inline{None}. We’ll expand on this in just
  a moment.
}
}



@@ 215,7 215,7 @@ If you’re wondering why ◊code-inline{output1} and
◊code-inline{uncons1} end in ◊code-inline{1}; it’s because they work
on individual elements. There are other ◊code-inline{output}
and ◊code-inline{uncons} functions that use ◊em{chunks} instead, but
since you might not know what chunks are we’re sticking to the basics.
since chunks aren’t relevant here we’re sticking these ones.
}

◊p{

M src/chapters/fs2/streams-and-pipes.html.pm => src/chapters/fs2/streams-and-pipes.html.pm +1 -6
@@ 53,8 53,6 @@ using any number of functions on the

◊snippet[#:name "rolling"]{}

◊todo{is a bit boring to keep using let’s check it works}

◊p{We can check it works by running the stream:}

◊snippet[#:name "rolling-test"]{}


@@ 127,7 125,7 @@ box. We can check the box once we’ve finished running the stream.}

◊items{
◊item{
The pipe has an ◊code-inline{IO} effect — this is because adding jiaozi to
The pipe has an ◊code-inline{IO} effect. This is because adding jiaozi to
the box an effectful operation. 
}
◊item{The pipe outputs ◊code-inline{Nothing}. Since all jiaozi are


@@ 176,9 174,6 @@ If not, why?}

◊headline-link{The crux of the problem}

◊todo{It’s more like serve and store}


◊p{The problem lies within our ◊code-inline{serve} pipe. We’re using
◊code-inline{take} to serve the jiaozi.}