Skip to content

Instantly share code, notes, and snippets.

View johnynek's full-sized avatar

P. Oscar Boykin johnynek

View GitHub Profile
@johnynek
johnynek / almosttailrec.scala
Last active May 13, 2024 02:10
A generalization of tail recursion for stack safety in scala
/*
* Consider a simple recursive function like:
* f(x) = if (x > 1) f(x - 1) + x
* else 0
*
* This function isn't tail recursive (it could be, but let's set that aside for a moment).
* How can we mechanically, which is to say without thinking about it, convert this into a stack safe recursion?
* An approach is to model everything that happens after the recursion as a continuation, and build up that
* continuation in a stack safe manner. Here is some example code:
*/
@johnynek
johnynek / Cargo.toml
Last active February 1, 2024 11:38
a toy example of CSV wordcount.
[package]
name = "hello"
version = "0.1.0"
authors = ["P. Oscar Boykin <boykin@pobox.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
csv = "1.1"
@johnynek
johnynek / scalding_alice.scala
Created July 18, 2014 17:15
Learn Scalding with Alice
/**
git clone https://github.com/twitter/scalding.git
cd scalding
./sbt scalding-repl/console
*/
import scala.io.Source
val alice = Source.fromURL("http://www.gutenberg.org/files/11/11.txt").getLines
// Add the line numbers, which we might want later
val aliceLineNum = alice.zipWithIndex.toList
@johnynek
johnynek / AliceInAggregatorLand.scala
Last active January 24, 2024 19:38
A REPL Example of using Aggregators in scala
/**
* To get started:
* git clone https://github.com/twitter/algebird
* cd algebird
* ./sbt algebird-core/console
*/
/**
* Let's get some data. Here is Alice in Wonderland, line by line
*/
@johnynek
johnynek / RefMap.scala
Last active April 14, 2023 13:04
A wrapper on ConcurrentHashMap to use with cats.effect.Ref
package org.bykn.refmap
import cats.data.State
import cats.effect.Sync
import cats.effect.concurrent.Ref
import java.util.concurrent.ConcurrentHashMap
import cats.implicits._
/**
@johnynek
johnynek / NatMatch.scala
Created January 10, 2023 18:40
Attempt to use scala match types to make a Nat
package dev.posco.nui
import scala.compiletime.{erasedValue, error, ops, requireConst}
object NatExample {
sealed trait Nat
object Nat {
case object Zero extends Nat
case class Succ[N <: Nat](prev: N) extends Nat
@johnynek
johnynek / sortmerge.scala
Last active October 14, 2022 10:32
merge sorted streams with fs2
import fs2.{Chunk, Stream, Pull}
import cats.collections.Heap
import cats.implicits._
object SortMerge {
def sortMerge[F[_], A: Ordering](streams: List[Stream[F, A]]): Stream[F, A] = {
implicit val ord: cats.Order[Stream.StepLeg[F, A]] =
new cats.Order[Stream.StepLeg[F, A]] {
val ordA = implicitly[Ordering[A]]
@johnynek
johnynek / Monad.scala
Created December 3, 2012 00:25
Short Monad Example in Scala
// Run this with: scala Monad.scala
trait Monad[M[_]] {
// in haskell, called return, but that's a reserved word
// constructs a Monad instance from the given value, e.g. List(1)
def apply[T](v: T): M[T]
// flatMap function, in scala:
def bind[T,U](m: M[T])(fn: (T) => M[U]): M[U]
// Laws these must follow are:
// identities:
@johnynek
johnynek / dep_clean.py
Created January 24, 2018 17:17
Tool to remove unused deps by brute force on bazel. Stolen shamelessly from Andrew Buss
#!/usr/bin/env python
import sys
# on osx you want brew install gnu-sed to get gsed
from sh import cp, rm, gsed, bazel, ErrorReturnCode
test_fn = lambda: bazel('build', sys.argv[1])
filename = sys.argv[2]
print "Checking that tests pass before starting"
print test_fn()
@johnynek
johnynek / typed_record.scala
Created June 25, 2021 19:05
An example of zero cost addition of types on top of `Map[String, Any]` to model generic records in scala 3
package example
object RecMap {
object Record {
// use this scope to bound who can see inside the opaque type
opaque type Rec[A <: Tuple] = Map[String, Any]
object Rec {
type HasKey[A <: Tuple, K] =