Skip to content

Instantly share code, notes, and snippets.

@mattdenner
mattdenner / gist:5728014
Last active December 18, 2015 04:49
This was my rewriting of "An exercise in Refactoring - Playing around with Monoids and Endomorphisms" (http://debasishg.blogspot.in/2013/03/an-exercise-in-refactoring-playing.html). There are probably ways of doing this better and I'd love to hear about them. Note: I found `clojure.core.reducers/monoid`
; Functions can be seen as endomorphisms, hence they are a monoid, which is available
; in the reducers library!
(use '[clojure.core.reducers :as reducers :only (monoid)])
(def FunctionMonoid
(reducers/monoid
comp ; append
(fn [] (fn [v] v)))) ; zero
; Here is a function that, given a boolean, returns another function that
; will either return the function f passed to it, or m-zero. The former happens
@mattdenner
mattdenner / gist:4977805
Created February 18, 2013 14:28
Me attempting to get my head around monads.

My biggest problem with monads is that my brain can't grasp them, obviously! One of the issues I've got is that people teach them as part of a somewhat bigger context: they start showing how Option[T] works and then suddenly declare ''Option[T] is a monad''! Or worse, they talk about something completely unrelated in an attempt to give you some real world perspective onto them. It's not working for me and it might not be working for you; what I'll write here is to help me understand monads, and it probably won't work for you, but it might.

I'm going to start with an extremely simple case class and build it up from there:

final case class Holder[+T](value: T)

It's really simple in that it holds a value of a type T. One thing to realise is that case class in Scala automatically gives you a companion object for Holder[T] called Holder which gives you an apply method for creating instances. I'm going to make a similar object, which I'll abitrarily call HolderMonad, that will have

sealed trait Validation[+E, +A] {
def fold[X](failure: E => X = identity[E] _, success: A => X = identity[A] _): X
def map[B](f: A => B): Validation[E, B];
}
final case class Success[E, A](a: A) extends Validation[E, A] {
def fold[X](failure: E => X = identity[E] _, success: A => X = identity[A] _): X = success(a)
def map[B](f: A => B): Validation[E, B] = Success(f(a))
}

In this YOW! 2012 video Tony Morris writes a piece about composing IO monads on the whiteboard and I was wondering if it basically boils down to the following Scala trait:

trait IO[A] {
  def flatMap[B](f: A => IO[B]): IO[B]
}
def inner(&block)
puts "BEFORE YIELD"
x = yield
puts "AFTER YIELD"
x
ensure
puts "ENSURE YIELD"
end
def call_inner_with_return
def needed?(a, b)
return false if a.nil?
unless b.nil?
unless b.t2?
if a.t1?
return true
end
end
else
if a.t1?
@mattdenner
mattdenner / gist:1064583
Created July 5, 2011 09:56
ActiveRecord is missing a middle ground between 'save' and 'save!'

I recently read Exceptional Ruby written by Avdi Grimm and, whilst I was generally impressed with it (it's worth a read, it made me think about things I do) there's one bit that I still struggle to approve of: using ActiveRecord::Base#save rather than ActiveRecord::Base#save!. It's not that I disagree with Avdi's sentiments, that exceptions should only be used in exceptional circumstances, but that ActiveRecord doesn't provide the middle ground that I think is needed.

My problem with save is that it relies on the developer calling it to check the return result which, from bitter experience, doesn't always happen.

What I want to see is something like this:

my_record.save do
  # Something went wrong, clean up!
  return 

end

@mattdenner
mattdenner / gist:1033476
Created June 18, 2011 20:21
Trying to work out why Rubinius takes 30+s longer than MRI 1.8.7

Running a small feature of our application:

time bundle exec cucumber -r features features/small_feature.feature

ruby 1.8.7 (2010-08-16 patchlevel 302) [i686-darwin10.4.3]
  1 scenario (1 passed)
  22 steps (22 passed)
  0m5.951s

real 0m18.358s

@mattdenner
mattdenner / gist:985791
Created May 22, 2011 19:37
Handy tip for using proxy_owner in named scopes
class Thing < ActiveRecord::Base
# This named scope is supposed to take in an instance of Owner so that it can be used. Normally people would start
# writing `Thing.something(Owner.first).first` but ...
named_scope :something, lambda { |owner|
# Something here using 'owner'
}
end
class Owner < ActiveRecord::Base
# ... this association uses the method_missing behaviour of associations to cheat the appearance of something. In
@mattdenner
mattdenner / gist:881227
Created March 22, 2011 13:49
Be careful when putting :group on an association used as in a has_many :through, but be aware that it can sometimes give a considerable performance improvement!

I've been trying to track down a performance problem (one of many) within our application that sucks 200 seconds (or more) when doing something really simple. The design of the model is this:

class Study
  has_many :requests
  has_many :projects, :through => :requests, :uniq => true
end

Essentially we have a study that can request some work to be done in our laboratories and that work is done as part of a project, which is responsible for paying for it later. So a study can be related to many projects through the work it has requested.

This all works fine until you want to do eager loading of the projects association, specifically within a query for multiple studies. For example, the killer query comes from: