Skip to content

Instantly share code, notes, and snippets.

View quelgar's full-sized avatar
🇦🇺

Lachlan O'Dea quelgar

🇦🇺
View GitHub Profile
@quelgar
quelgar / TRingBuffer.scala
Created May 23, 2022 05:34
A ring buffer implementation for ZIO STM
import zio.stm.*
import zio.prelude.*
final class TRingBuffer[A] private (array: TArray[A], stateRef: TRef[TRingBuffer.State]) {
import TRingBuffer.*
private def uncheckedRead(state: State): USTM[A] = array(state.start) <*
stateRef.set(state.copy(start = (state.start + 1) % capacity, size = state.size - 1))
@quelgar
quelgar / typed_errors.md
Last active January 16, 2024 09:36
Every Argument for Static Typing Applies to Typed Errors

Every Argument for Static Typing Applies to Typed Errors

Think of all the arguments you've heard as to why static typing is desirable — every single one of those arguments applies equally well to using types to represent error conditions.

An odd thing I’ve observed about the Scala community is how many of its members believe that a) a language with a sophisticated static type system is very valuable; and b) that using types for error handling is basically a waste of time. If static types are useful—and if you like Scala, presumably you think they are—then using them to represent error conditions is also useful.

Here's a little secret of functional programming: errors aren't some special thing that operate under a different set of rules to everything else. Yes, there are a set of common patterns we group under the loose heading "error handling", but fundamentally we're just dealing with more values. Values that can have types associated with them. There's absolutely no reason why the benefits of static ty

@quelgar
quelgar / Framing.scala
Last active March 15, 2019 02:55
A sink to frame a ZIO stream by delimited boundaries. (eg lines of text)
import scalaz.zio.console._
import scalaz.zio.stream._
import scalaz.zio.{Chunk, ZIO}
object Framing {
def lfDelimiter = Chunk('\n')
@quelgar
quelgar / ZioInputStreamTest.scala
Last active October 27, 2019 14:44
Inputstream to ZIO Stream of byte chunks.
import java.io.InputStream
import java.nio.file.{Files, Path, Paths}
import scalaz.zio.console.putStrLn
import scalaz.zio.duration._
import scalaz.zio.stream.Stream
import scalaz.zio.stream.Stream.Fold
import scalaz.zio.{App, Chunk, IO, Managed}
@quelgar
quelgar / ConnectableTest.scala
Last active June 25, 2018 01:55
Testing reliably subscribing to a Monix ConnectableObservable before connecting.
package au.com.str.stellar
import cats.implicits._
import monix.eval.{Task, TaskApp}
import monix.reactive.Observable
import scala.concurrent.duration._
object Test extends TaskApp {
@quelgar
quelgar / Framing.scala
Last active January 19, 2018 00:11
Monix Pipe for byte stream framing
import java.nio.ByteBuffer
import monix.nio.text.UTF8Codec._
import monix.nio.file
import monix.reactive._
import monix.reactive.observers.Subscriber
import monix.execution._
import monix.execution.exceptions
import monix.execution.atomic.Atomic
import monix.reactive.subjects.Subject
@quelgar
quelgar / MonixNioTest.scala
Last active August 22, 2017 00:39
Testing accepting TCP connections with Monix NIO.
package monix.rsocket.tcp
import java.nio.charset.StandardCharsets
import monix.eval.{Callback, Task}
import monix.reactive.Observable
import monix.nio.tcp._
import monix.execution.Scheduler.Implicits.global
import monix.reactive._
import monix.execution._
import Ack.{Stop, Continue}
import scala.util.control.NonFatal
import scala.concurrent._
import scala.concurrent.duration._
def feed[A](in: Iterator[A], out: Observer[A])
(implicit s: Scheduler): Future[Ack] = {
@quelgar
quelgar / GADT.scala
Created March 10, 2017 01:32
Basic GADT in Scala
// Scala version of code from https://en.wikipedia.org/wiki/Generalized_algebraic_data_type
sealed abstract class Expr[A]
final case class EBool(a: Boolean) extends Expr[Boolean]
final case class EInt(a: Int) extends Expr[Int]
@quelgar
quelgar / CacheStage.scala
Last active February 10, 2019 01:16
**NOTE**: I think this turned out to be pretty buggy. A custom Akka graph stage that caches the latest value for a period of time.
import java.time.{Clock, Instant}
import akka.NotUsed
import akka.actor.ActorSystem
import akka.stream.{Attributes, FlowShape, Inlet, Outlet, _}
import akka.stream.stage.{GraphStage, GraphStageLogic, InHandler, OutHandler, _}
import scaladsl.{Flow, _}
import scala.concurrent.Await
import scala.concurrent.duration._