Skip to content

Instantly share code, notes, and snippets.

@jodersky
jodersky / git-wip
Last active March 29, 2023 15:32
A custom git script which is helpful if you work on many branches concurrently and forget their names
#!/bin/bash
USAGE="<pattern>"
LONG_USAGE="list most recently used branches that start with <pattern>"
# shellcheck source=/dev/null
. "$(git --exec-path)/git-sh-setup"
branches=$(git branch --sort=committerdate --list "$1*" --no-merged master --format='%(refname:short)'| tail -n 5)
for branch in $branches; do
@jodersky
jodersky / ANSI.md
Created January 15, 2023 12:23 — forked from fnky/ANSI.md
ANSI Escape Codes

ANSI Escape Sequences

Standard escape codes are prefixed with Escape:

  • Ctrl-Key: ^[
  • Octal: \033
  • Unicode: \u001b
  • Hexadecimal: \x1B
  • Decimal: 27
@jodersky
jodersky / LambdaUtil.scala
Created January 10, 2023 15:52
utilities for serializing and deserializing functions
object LambdaUtil:
import java.lang.invoke.{MethodHandleInfo, SerializedLambda}
def serializeLambda(closure: AnyRef): Array[Byte] =
val writeReplace = closure.getClass.getDeclaredMethod("writeReplace")
writeReplace.setAccessible(true)
val serializable = writeReplace.invoke(closure).asInstanceOf[SerializedLambda]
val bytes = new java.io.ByteArrayOutputStream
val os = new java.io.ObjectOutputStream(bytes)
def hexify(bytes: Array[Byte]): String = {
val builder = new StringBuilder
for (i <- 0 until bytes.length) {
val b = bytes(i)
val upperNibble = (b >>> 4) & 0x0f
val lowerNibble = b & 0x0f
builder += Character.forDigit(upperNibble, 16)
builder += Character.forDigit(lowerNibble, 16)
}
builder.result()
class FunctionExractor(using qctx: Quotes) {
import qctx.reflect._
private case class ToReplace(
outerSymbol: Symbol, // where the container originally comes from, used to collect inputs to the dep
innerTpe: TypeRepr // the original container's partition type
)
/**
@jodersky
jodersky / build.sc
Last active March 31, 2021 18:45
Mill javah
import mill._, scalalib._
trait JavahModule extends JavaModule {
def javah = T {
os.walk(compile().classes.path).filter(_.ext == "class").foreach { path =>
sgjavah.javah(
path.toNIO,
T.dest.toNIO
)
@jodersky
jodersky / millinit
Last active March 6, 2021 18:23
Initialize a directory with a basic Mill build configuration, using the latest available version of Mill
#!/bin/bash
#
# millinit - fetch mill and initialize a project in a directory
#
# This script will query GitHub to find the newest available version of Mill. It
# will download it and initialize a directory with a basic build configuration.
#
# Usage: millinit <directory>
set -o errexit
@jodersky
jodersky / build.sc
Created March 6, 2021 17:23
Combining scaladoc from multiple sources in mill
// This module isn't really a ScalaModule, but we use it to generate
// consolidated documentation using the Scaladoc tool.
object docs extends ScalaModule {
def scalaVersion = "3.0.0-M3"
def docSource = T.source(millSourcePath)
def moduleDeps = Seq(
...
@jodersky
jodersky / pickler.scala
Created May 26, 2020 17:57
Simple ujson-based pickler using Dotty typeclass derivation
import scala.deriving._
import scala.compiletime.{erasedValue, summonInline}
// super primitive (but composable via typeclass derivation) JSON reader
trait Reader[A] {
def read(json: ujson.Value): A
}
object Reader {
given Reader[Int] = new Reader[Int] {

In my experience, the following libraries and tools help you build Scala applications very quickly. They all require miminal setup ceremony and target the most common use-cases, without the user needing to learn new domain specific languages. Many of them take inspiration from Python's philosophy of keeping things simple (yet they are still statically typed). As such, they may not be all you ever need, but they should help you build solid applications relatively quickly.

These are of course subjective recommendations, including shameless plugs.