Skip to content

Instantly share code, notes, and snippets.

View kputnam's full-sized avatar
💭
I have 478 browser tabs open

kputnam kputnam

💭
I have 478 browser tabs open
View GitHub Profile
@kputnam
kputnam / SqlParser.scala
Created October 19, 2010 19:11
Parses a trivial subset of SQL
trait SqlParser extends scala.util.parsing.combinator.RegexParsers {
// ignore ordinary whitespace, line comments, and inline comments between combinators
override val whiteSpace = "(?sm)(\\s*(?:--.*?$|/\\*((?!\\*/).)*\\*/)\\s*|\\s+)+".r
def sqlStatement: Parser[Statement] =
opt(whiteSpace) ~> positioned( procedureCallStatement
| insertStatementCustom
| insertStatement
| updateStatement
object Unfold {
/**
* Builds a list by recursively applying `f`, until `f` returns None
*
* @param seed the initial value passed to `f`
* @param f returns Some(Pair(element, nextSeed)) where `element` is added
* to the list and `nextSeed` is passed to `f` on the next invocation.
*/
def buildList[T, R](seed: T)(f: T => Option[Pair[R, T]]): List[R] =
@kputnam
kputnam / worker-group.js
Created November 4, 2011 22:05
Group of Asynchronous Workers
/**
* Starts all workers at once and executes the given afterFinish
* callback when all workers have completed. Workers are expected
* to signal when they are finished.
*
* @example
*
* WorkerGroup(
* [ function(whenDone) { $.ajax({url: 'http://jquery.com/a/', error: whenDone, success: whenDone}); }
* , function(whenDone) { $.ajax({url: 'http://jquery.com/b/', error: whenDone, success: whenDone}); }
@kputnam
kputnam / throttled-worker-group.js
Created November 4, 2011 22:14
Throttled Group of Asynchronous Workers
/**
* Executes no more than maxConcurrency workers at once and executes the
* given afterFinish callback when all workers have completed. Workers are
* expected to signal when they are finished.
*
* @example
*
* WorkerGroup(
* [ function(whenDone) { $.ajax({url: 'http://jquery.com/a/', error: whenDone, success: whenDone}); }
* , function(whenDone) { $.ajax({url: 'http://jquery.com/b/', error: whenDone, success: whenDone}); }
@kputnam
kputnam / .vimrc
Created January 27, 2012 23:11
Markdown settings for vim
set wrap " changes text display, doesn't change the buffer
set linebreak " break at word boundaries, instead of mid-word
" gq will reformat text to wrap at boundaries
set textwidth=78 " wrap text as its being typed
set wrapmargin=0
@kputnam
kputnam / collect.txt
Created February 16, 2012 09:30
Float distribution in QuickCheck
Prelude Test.QuickCheck> let f n = case span (/= '.') (show n) of (a,b) -> (length a, length b)
Prelude Test.QuickCheck> quickCheck (\x -> collect (f x) $ x /= 0.04882)
+++ OK, passed 100 tests:
28% (3,15)
15% (2,16)
15% (2,15)
8% (4,15)
8% (3,16)
5% (3,14)
5% (1,16)
@kputnam
kputnam / state.coffee
Created April 2, 2012 23:51
State monad in CoffeeScript
# Actions
###################################################################
put = (n) -> (state, count) ->
{state: n, value: null, count: count + 1}
get = (state, count) ->
{state: state, value: state, count: count}
update = (f) -> (state, count) ->
@kputnam
kputnam / io-sugar.coffee
Created April 3, 2012 02:48
IO monad in CoffeeScript
# Syntax sugar, more or less: wrap each monadic action with
# another function that binds to the next action `k`.
####################################################################
confirm_ = (msg, k) ->
bind confirm(msg), k
alert_ = (msg, k) ->
bind alert(msg), k
prompt_ = (msg, detent = "", k) ->
@kputnam
kputnam / u.js
Created July 12, 2012 23:46
Functional combinators in JavaScript
var u = (function() {
var id = function(x) { return x; }
, single = function(x) { return [x]; }
, constant = function(x) { return function() { return x; }};
var curried = function(f, n, args) {
return (args.length >= n)
? f.apply(null, args)
: function() { return curried(f, n, args.concat(slice(arguments))); }; };
@kputnam
kputnam / on_duplicate_key_update.rb
Created November 3, 2012 02:11
Patch ActiveRecord + Arel to support INSERT ... ON DUPLICATE KEY UPDATE ...
#
# I'd prefer to add a parameter to ActiveRecord::Base.create (and .save)
# which would look like this:
#
# user.save(on_duplicate_key_update: true)
#
# User.create(attrs, on_duplicate_key_update: %w(updated_at))
#
# But those methods are already overloaded and it seems like any methods,
# even new ones we could add, would require some painful plumbing to pass