Skip to content

Instantly share code, notes, and snippets.

View lancegatlin's full-sized avatar

Lance Gatlin lancegatlin

View GitHub Profile
Typemax 2.0 1KC base layout preview
Note1: orientation below is with Twiddler back in palm keys facing out (right or left handed)
Note2: all scores below are in 1000th of a percentage of all bigrams e.g. 1041 = 1.041% of all bigrams occurences
Note3: SPACE frequency calculated as follows: average 4.79 letters per word => 1 space for every 4.79 letters => 1/5.79 characters = 17.3% spaces => 4.79/5.79 = 82.7% letters
Note4: percentage-scores are normalized against frequency of SPACE (17.3% of all letters) to compute total load since http://norvig.com/mayzner.html does not provide letter percentages including SPACE e.g. E => 12.49% * (1-0.173=0.827) = 10.33% including SPACE
.-------------------.
| Inner | Outer |
.-------------------.
Lance is a professional Scala adventurer, open source loner, longevity nut and semi-regular awkward dancer. Lance has been exploring Scala for the last 6 years and recently renewed his Scala vows on his Scala-versary: "I'll never quit you... not like those others". Lance enjoys polishing his shiny sword of functional programming +2 but finds his patrons prefer just "getting things done" with their rusty daggers. Lance also used to do a lot of improv, has deep thoughts about one-handed typing and will win, eventually, by living longer than everyone else.
"Finally! Tagless and Fancy Free Monads"
In this talk, we'll explore "final tagless" as an alternative to the free monad.
At the end of this talk, you'll know:
* How to write Scala "final tagless" languages, bridges and interperters
* If monads are evil and the work of "he who shall not be named"
* The pros and cons between the free monad and "final tagless"
* Some suggestions on when to use the free monad or "final tagless"
Transcendicant:
One who dedicates their life to continuous, incremental all-self-improvement
* To seek the highest state of self freedom
* To grow resilient enough to hold and learn from all experience: the undesired, the shameful, the confused
* To sit in the discomfort of ultimate uncertainty, incompleteness, wrongness and unknowing
* To observe shame as the instinct to hide one's wrongness from others and self
* To discern and accept the utility of self-stories, ego-delusion and social programming, the useful illusions
* To continously renew the facts and data of being and re-tell only the smallest story necessary to act in the world
* To discard unneeded illusions and imagine beyond today's useful illusions
* To create new ways of thinking, new ways of being, new useful illusions
import sbt.Keys._
import sbt._
object IntegrationTest {
// Select integration tests that use local running resources
lazy val IntgLocalTest = config("intg_local") extend Test
// Select integration test that connect to dev env
lazy val IntgDevTest = config("intg_dev") extend Test
// Select all integration tests
lazy val IntgTest = config("intg") extend Test
import sbt.Keys._
import sbt._
object CleanUpSlf4j {
// fix multiple slf4j deps
// see https://stackoverflow.com/questions/25208943/how-to-fix-slf4j-class-path-contains-multiple-slf4j-bindings-at-startup-of-pl
val settings : Seq[Def.Setting[_]] = Seq(
libraryDependencies ++= Seq(
Dependencies.slf4j,
Dependencies.logback
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
</appender>
// LESSON1: to return an Iterator, must pass in a reference (since Iterator always references something)
// LESSON1a: more generally, to return any type that "points" at data (i.e. whose lifetime is based on the lifetime of the input), must pass in a reference
// fn lesson1_broken(from: String) -> impl Iterator<Item=&str> {
// from.split(' ') // Iterator produced from borrow of from
// // from goes out of scope
// }
fn lesson1_fixed1(from: &mut String) -> impl Iterator<Item=&str> {
/* Keypad to Karabiner mapping (to avoid interference with regular keyboard)
* note: using device id would make all this unnecessary
* ,---------------------------------------------. ,--------------------------------.
* | KP_COMMA | KP_1 | KP_4 | KP_7 | NUMLOCK | | lang1 | f22 | f19 | f16 | f13 |
* |----------+------+------+------+-------------| |--------+-----+-----+-----+-----|
* | KP_0 | KP_2 | KP_5 | KP_8 | KP_SLASH | | lang2 | f23 | f20 | f17 | f14 |
* |----------+------+------+------+-------------| |--------+-----+-----+-----+-----|
* | KP_DOT | KP_3 | KP_6 | KP_9 | KP_ASTERISK | | lang3 | f24 | f21 | f18 | f15 |
* `---------------------------------------------' `--------------------------------'
* ,-------------------------------. ,----------,-----------------.
/**
* Create an ExecutionContext for blocking operations that grows with demand
*
* @param threadNamePrefix the prefix to put at the beginning of the name of threads for this pool
* @param unhandledExceptionLogger a function to log unhandled exceptions
* @param minPoolSize the minimum number of threads to allocate for this pool
* @param maxPoolSize the maximum allowed number of threads to allocate for this pool (requests beyond
* this maximum will block the thread of the requester)
* @param keepAliveTime the amount of time to keep an unused thread alive before destorying it
* @return an ExecutionContext for blocking operations