yapee makes programs

Likes programs. Would like to learn to make them one day.

Read this first

Nested data structures with functional lenses

The concept I’m going to describe here is far from new, however I found that there wasn’t a good Elixir library that implemented it so I wrote one (https://hex.pm/packages/lens). If you’re familiar with lenses, then you’ll probably not find anything new in the post, just go and use the library.

Still here? Great. So what does lens do? You can think about this like Elixir’s get_in/update_in on steroids. Where in the case of get_in/update_in you can describe a path to a single value (with the narrow exception of Access.all), lens allows you to describe a path to many values and get or update all of them with one function call. In fact lenses in lens are compatible with get_in/update_in. Also note that when I say “update” I mean that in the functional sense - create a new datastructure that’s mostly the same except for the parts we’re “updating”.

For example you can use Lens.filter like A...

Continue reading →


About celluloid

An actor library in ruby called celluloid is trying a creative approach to the problem of slow operations blocking threads. But, it’s important to be aware of the tradeoffs that are taken to achieve the benefits they tout. The celluloid documentation tells us:

Each actor is a concurrent object running in its own thread, and every
method invocation is wrapped in a fiber that can be suspended whenever
it calls out to other actors, and resumed when the response is available.

Let’s take it for a spin:

# I'm using jruby to run this example

class SlowCounter
  include Celluloid

  def initialize
    @count = 0
  end

  def inc
    temp = @count
    sleep 0.1
    @count = temp + 1
  end

  def get
    @count
  end
end

counter = SlowCounter.new
threads = 10.times.map { Thread.new { 10.times { counter.inc } } }
threads.each(&:join)

p counter.get

You might have expected this code to...

Continue reading →


Benefits of the erlang scheduler

Elixir has a certain advantage when it comes to writing actor code over other systems of that type. This advantage is thanks to running on top of erlang’s BEAM VM. What’s more it cannot be easily replicated when concurrency is based on system threads.

 The situation in ruby

Let’s consider these two actors:

# I'm using concurrent-ruby running on jruby for these ruby samples


# record_execution is a method that just atomically increments a named counter

class ActorA < Concurrent::Actor::RestartingContext
  def on_message(msg)
    record_execution(:actor_a)
    sleep(2) # slow operation
  end
end

class ActorB < Concurrent::Actor::RestartingContext
  def on_message(msg)
    record_execution(:actor_b)
    # do nothing, i.e. a fast operation
  end
end

Now let’s say we start these 2 actors and send each 100 messages. After 10 seconds our execution counts will probably look something...

Continue reading →


More math in code

So why does math work? Or rather why does it work out? Why are you never surprised that there is a corner case where 1037 + 1 = 1039 instead of the expected 1038? Of course you could define such math. You just don’t because it’s not that useful. Why do we define such programs then?

Haskell is mathy in its structure. And that’s not only due to the high level of abstraction of some of the concepts. Instead the key here is that the concepts state and obey some rules. Just like addition obeys some set of rules and you are never surprised by the result. The amount of deviation is minimal which results in clean blocks that fit together to form larger constructs. Like legos.

The most common example of not-enough-math is mutability. Consider:

f(x) == f(x)

This is always true in mathematics. Not so in programs. And I’m not even talking about side effects like network calls or database...

Continue reading →


Against (company) setup scripts

I recently reinstalled from scratch to El Capitan (I have to say it’s pretty neat) and of course had to go through the ordeal of setting up my dev environment.

The company I work for has long battled to create some kind of setup script that will make this process easier, installing tools like rbenv downloading projects, setting up nginx, and so on. There have been a couple separate attempts, all in different states of disrepair at this point so I decided to use none of them and brave the process on my own, possibly learning something. And lo and behold - it wasn’t so bad!

It actually took me just an evening and a day to get everything set up with the projects I usually work in. I’m now also much more confident that I can debug this setup when something goes wrong compared to the much more opaque setup scripts I used in the past. Huh. Who knew?

It seems to me that a setup script is a...

Continue reading →


Code as data is just annotated functions?

What I wrote previously might just boil down to having a bunch of annotations on your functions. In a functional language a lot of your functions will look something like this:

(defn new-functionality [x]
  (-> x
    first-step
    second-step
    third-step))

For those not in the know -> is the threading macro, the usage of which I’m probably misrepresenting here, but which pipes it’s first argument through a pipeline built out of the rest of the arguments. So this example is the same as:

(defn new-functionality [x]
  (third-step (second-step (first-step x))))

Or imperatively:

def new_functionality(x)
  a = first_step(x)
  b = second_step(a)
  return third_step(b)
end

The thing is that by default this structure is internal to the function and cannot be extracted. Of course macros in languages such as clojure or Elixir should allow one to pick apart the parse tree of a function...

Continue reading →


Code as data

Some tasks seem to be much simpler if the code of our doohickey was all data instead. Like if I could write:

(endpoint "create_contact"
  modules [require-user name-validator email-validator]
  implementation endpoints/create_contact
)

And then there would be code that magically output documentation with validations, param names and such. Or produced a list of endpoints by authentication method. This second task seems to be impossible for a more traditional arrangement where the authentication might be squirreled away in imperative code:

def create_contact
  raise Unauthenticated unless current_user.present?
  Contact.create(params)
end

This seems like a more difficult way to program though, or at least a more unfamiliar one. Instead of telling the computer what you want it to do step by step you have to build some kind of structure out of blocks. And if the blocks you want are not...

Continue reading →