Skip to content

Instantly share code, notes, and snippets.


Mike Hearn mikehearn

View GitHub Profile
View BriefLogFormatter.kt
// A couple of inlined utility functions: the first is just a syntax convenience, the second lets us use
// Kotlin's string interpolation efficiently: the message is never calculated/concatenated together unless
// logging at that level is enabled.
inline fun <reified T : Any> loggerFor(): org.slf4j.Logger = LoggerFactory.getLogger(
inline fun org.slf4j.Logger.trace(msg: () -> String) {
if (isTraceEnabled) trace(msg())
* A Java logging formatter that writes more compact output than the default.
mikehearn / puzzle.kt
Created Feb 9, 2016
Kotlin version of the NYT Puzzles program
View puzzle.kt
import kotlin.system.measureTimeMillis
fun main(args: Array<String>) {
val name = if (args.size > 1) args[0] else "/usr/share/dict/words"
val time = measureTimeMillis {
repeat(200) {
mikehearn / KotlinDuckTyping.kt
Created Dec 18, 2015
Kotlin duck typing / type classing fiddle
View KotlinDuckTyping.kt
class A {
fun shout() = println("go team A!")
class B {
fun shout() = println("go team B!")
interface Shoutable {
fun shout()
mikehearn / Kryo Kotlin class serialiser.kt
Created Dec 17, 2015
A Kryo serialiser that lets you serialise immutable classes like "class Foo(val a: Int, val b: Bar)" without bypassing the c'tor.
View Kryo Kotlin class serialiser.kt
interface SerializeableWithKryo
class ImmutableClassSerializer<T : SerializeableWithKryo>(val klass: KClass<T>) : Serializer<T>() {
val props = klass.memberProperties.sortedBy { }
val propsByName = props.toMapBy { }
val constructor = klass.primaryConstructor!!
init {
// Verify that this class is immutable (all properties are final)
assert(props.none { it is KMutableProperty<*> })
mikehearn / linear.kt
Created Dec 14, 2015
Rough sketch of possible linear types in kotlin (doesn't work with today's compiler)
View linear.kt
open class LinearVal<T>(private val _v: T) {
open operator fun invoke(): T {
return _v
inline fun move(): LinearVal<T> {
if (this !is UnavailableLinearVal)
throw AssertionError()
return __dupe()
mikehearn / threadbox.kt
Created Aug 15, 2015
More advanced ThreadBox with affinity guards
View threadbox.kt
// This is a class that attempts to stop you accessing variables outside a lock.
// It does not do a perfect job, but can catch some common kinds of mistake, in
// particular when you accidentally try to work with objects inside closures that
// end up running later, outside the locked region (or in a different thread).
val bank = ThreadBox(object {
val accounts by arrayListOf(10, 0, 0, 0).guard()
mikehearn / gist:7274375de2950e10f56f
Last active Aug 29, 2015
View gist:7274375de2950e10f56f
class ThreadBox<T>(private val data: T) {
synchronized fun use<R>(block: (T) -> R): R = block(data)
synchronized fun useWith<R>(block: T.() -> R): R = data.block()
class UIThreadBox<T>(private val data: T) {
fun use(block: (T) -> Unit): Unit = if (Platform.isFxApplicationThread()) block(data) else Platform.runLater { block(data) }
fun useWith(block: T.() -> Unit): Unit = if (Platform.isFxApplicationThread()) data.block() else Platform.runLater { data.block() }
/** Does a blocking get from the UI thread - danger of deadlock if not used properly! */
View gist:f639176566d735b676e7
public static class AnimatedBindInfo {
@Nullable public Timeline timeline;
public NumberBinding bindFrom;
public Runnable onAnimFinish;
public static AnimatedBindInfo animatedBind(Node node, WritableDoubleValue bindTo, NumberBinding bindFrom) {
bindTo.set(bindFrom.doubleValue()); // Initialise.
bindFrom.addListener((o, prev, cur) -> {
AnimatedBindInfo info = (AnimatedBindInfo) node.getUserData();
mikehearn /
Last active Nov 18, 2020
Some code for JavaFX observable collections (maps and sets) which replicate changes between threads. From the open source, Apache licensed Lighthouse project. Check there for the latest code.
// Contact:
package lighthouse.threading;
import javafx.application.Platform;
import lighthouse.protocol.LHUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
View gist:1ab3d4b129803d1da46d
* This list is created by dynamically concatenating all the source lists together.
public class ConcatenatingList<T> extends ObservableListBase<T> implements ObservableList<T> {
private List<ObservableList<T>> sources = new ArrayList<>();
private ListChangeListener<T> listener = this::sourceChanged;
public ConcatenatingList(ObservableList<T>... source) {
You can’t perform that action at this time.