Skip to content

Instantly share code, notes, and snippets.

View djspiewak's full-sized avatar

Daniel Spiewak djspiewak

View GitHub Profile
[info] DispatcherSpec
[info] sequential dispatcher should
[info] await = true
[info] + reject new tasks while shutting down
[info] await = false
[info] + reject new tasks while shutting down
[info] parallel dispatcher should
[info] await = true
[info] + reject new tasks while shutting down
[info] await = false
@djspiewak
djspiewak / 0introduction.md
Last active November 28, 2023 15:03
Scala Collections Proposal

Collections Redesign Proposal

I'm going to start off by motivating what I'm doing here. And I want to be clear that I'm not "dissing" the existing collections implementation or anything as unproductively negative as that. It was a really good experiment, it was a huge step forward given what we knew back in 2.8, but now it's time to learn from that experiment and do better. This proposal uses what I believe are the lessons we can learn about what worked, what didn't work, and what is and isn't important about collections in Scala.

This is going to start out sounding really negative and pervasively dismissive, but bear with me! There's a point to all my ranting. I want to be really clear about my motivations for the proposal being the way that it is.

Problems

Generic Interfaces

How to GPG as a Scala OSS Maintainer

tl;dr Generate a GPG key pair (exercising appropriate paranoia). Send it to key servers. Create a Keybase account with the public part of that key. Use your keypair to sign git tags and SBT artifacts.

GPG is probably one of the least understood day-to-day pieces of software in the modern developer's toolshed. It's certainly the least understood of the important pieces of software (literally no one cares that you can't remember grep's regex variant), and this is a testament to the mightily terrible user interface it exposes to its otherwise extremely simple functionality. It's almost like cryptographers think that part of the security comes from the fact that bad guys can't figure it out any more than the good guys can.

Anyway, GPG is important for open source in particular because of one specific feature of public/private key cryptography: signing. Any published software should be signed by the developer (or company) who published it. Ideally, consu

Greasing the Skids: Building Remote Teams

In the wake of the virus that-must-not-be-named (which most people misname anyway), it seems like everyone and their cat has posted some sort of opinion or how-to on making remote work, work. This is a good thing! Working remotely, particularly full-time, is hard! I've done it for my entire career (aside from an odd 14 month office period in the middle that we shall not speak of), but more relevantly, for the past two years I've been responsible for building, managing, and enabling an entirely remote team, distributed across nine timezones. Remote teams don't just happen by installing Slack and telling everyone to work on their couch: they require a lot of effort to do correctly and efficiently. But, done right, it can be a massive multiplier on your team efficiency and flexibility.

Here's how we do it. I'm going to attempt to structure this post more towards management than engineering, and so I apologize in advance if I assume terminology or knowledge which

Easy Scala Publication

The following describes how you can publish artifacts for any sbt project using the GitHub Package Registry and the sbt-github-packages plugin.

Step 1: Create a GitHub Token

In your GitHub account, go to Settings > Developer settings > Personal access tokens, then click on Generate new token (or click here). Fill in some sort of meaningful name (I chose Dev) and click on the write:packages checkbox:

the new personal access token page with the above steps having been followed

package sillio
import cats.syntax.all._
import scala.annotation.tailrec
import scala.concurrent.ExecutionContext
import scala.util.control.NonFatal
import java.util.concurrent.atomic.{AtomicBoolean, AtomicReference}

A Workable Trust Model for sbt

I've been spending a lot of time recently thinking about trust as it relates to artifact publication. Some of this has led me to spend a bit more quality time with the implementations of sbt-pgp and sbt-gpg, some of it has led to raging despair and sadness, and some of it has led to what I think are productive lines of thought and potential action. This gist represents the last of those three.

All of this started with a question posed to me by Jakob Odersky: how can we make artifact verification usable and secure for everyone?

Note: I'm going to refer to the general library ecosystem as "Scala library authors". Really what I mean here is anyone who publishes to a public repository from which artifacts can be resolved, which in practice probably means Maven Central, Bintray, or a private Nexus.

Artifact Verification

[43/1037] shared[2.12.17].compile
[info] compiling 10 Scala sources and 1 Java source to /Users/daniel/Development/Scala/bloop/out/shared/2.12.17/compile.dest/classes ...
[info] done compiling
[77/1037] backend[2.12.17].compile
[info] compiling 58 Scala sources and 1 Java source to /Users/daniel/Development/Scala/bloop/out/backend/2.12.17/compile.dest/classes ...
[warn] one deprecation
[warn] one deprecation (since 3.0.0-RC2)
[warn] two deprecations in total; re-run with -deprecation for details
[warn] one feature warning; re-run with -feature for details
[warn] four warnings found

Explaining Miles's Magic

Miles Sabin recently opened a pull request fixing the infamous SI-2712. First off, this is remarkable and, if merged, will make everyone's life enormously easier. This is a bug that a lot of people hit often without even realizing it, and they just assume that either they did something wrong or the compiler is broken in some weird way. It is especially common for users of scalaz or cats.

But that's not what I wanted to write about. What I want to write about is the exact semantics of Miles's fix, because it does impose some very specific assumptions about the way that type constructors work, and understanding those assumptions is the key to getting the most of it his fix.

For starters, here is the sort of thing that SI-2712 affects:

def foo[F[_], A](fa: F[A]): String = fa.toString
/*
* Copyright 2020-2021 Typelevel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software