Skip to content

Instantly share code, notes, and snippets.

View phongngtuan's full-sized avatar

Phong Nguyen phongngtuan

View GitHub Profile

Understanding Comparative Benchmarks

I'm going to do something that I don't normally do, which is to say I'm going to talk about comparative benchmarks. In general, I try to confine performance discussion to absolute metrics as much as possible, or comparisons to other well-defined neutral reference points. This is precisely why Cats Effect's readme mentions a comparison to a fixed thread pool, rather doing comparisons with other asynchronous runtimes like Akka or ZIO. Comparisons in general devolve very quickly into emotional marketing.

But, just once, today we're going to talk about the emotional marketing. In particular, we're going to look at Cats Effect 3 and ZIO 2. Now, for context, as of this writing ZIO 2 has released their first milestone; they have not released a final 2.0 version. This implies straight off the bat that we're comparing apples to oranges a bit, since Cats Effect 3 has been out and in production for months. However, there has been a post going around which cites various compar

@SystemFw
SystemFw / Ex.scala
Last active November 3, 2018 17:41
Encoding existentials via abstract types (1) and higher-ranks (2)
// This is the traditional encoding, using abstract type members
// to encode existentials
object AbstractExistentials {
trait E {
type X
val x: X
def f(p: X): String
}
@calvinlfer
calvinlfer / README.md
Last active April 24, 2024 13:03
Developing an understanding of the FS2 Pull datatype

Developing an understanding of the FS2 Pull data type

In Pull[F, O, R], R is the return type. Pull represents a computation that emits some values on the Stream (of type O) and returns a new thing (R). In order to convert a Pull to a Stream, R must be Unit. This is because an FS2 Stream does not have the ability to terminate with a return value.

image

See here for the conversation

  • Stream[F, O] is monadic over O which are the output values emitted
  • Pull[F, O, R] is monadic over R which is used for stateful transformations
@Daenyth
Daenyth / Pull.md
Last active November 9, 2023 17:14
Designing an fs2 `Pull` from scratch

The problem

I have some data which has adjacent entries that I want to group together and perform actions on. I know roughly that fs2.Pull can be used to "step" through a stream and do more complicated logic than the built in combinators allow. I don't know how to write one though!

In the end we should have something like

def combineAdjacent[F[_], A](
 shouldCombine: (A, A) => Boolean,
@alexgian
alexgian / simply_redef.scm
Last active March 26, 2023 16:13
Allows the code in the book "Simply Scheme" to run on Racket.
#lang scheme/base
;;; ============================================================================
;;; Port of the "Simply Scheme" book code to allow use under Racket
;;; ============================================================================
;;; It allows re-defining of module functions, which was the main obstacle
;;; to its operation previously.
;;; The first part is an adaptation of the necessary changes to run on Racket
;;; by importing aliased existing module functions using "require" and "only-in"
;;; The second part is the (slightly adapted) code from
@Daenyth
Daenyth / MonadAndFs2Ops.md
Last active June 25, 2024 13:04
Cheat sheet for common cats monad and fs2 operation shapes
Operation Input Result Notes
map F[A] , A => B F[B] Functor
apply F[A] , F[A => B] F[B] Applicative
(fa, fb, ...).mapN (F[A], F[B], ...) , (A, B, ...) => C F[C] Applicative
(fa, fb, ...).tupled (F[A], F[B], ...) F[(A, B, ...)] Applicative
flatMap F[A] , A => F[B] F[B] Monad
traverse F[A] , A => G[B] G[F[A]] Traversable; fa.traverse(f) == fa.map(f).sequence; "foreach with effects"
sequence F[G[A]] G[F[A]] Same as fga.traverse(identity)
attempt F[A] F[Either[E, A]] Given ApplicativeError[F, E]